加工日志并做汇总
目标
使用 grep、sed、awk、cut、tr、sort、uniq 处理自己创建的日志,并通过 jq 和 yq 从结构化数据中提取值。
为什么重要
LFCS 的文本处理题考查的不是“是否记得一行标准答案”,而是能否按字段思考。如果用正则表达式扫描整行,连字节数列中的 500 也可能被匹配。因此应先确定状态码是第四个字段这一结构,再选择工具。聚合也是如此——sort | uniq -c | sort -rn 是常用模式,但如果不知道为什么前面必须先排序(uniq 只处理相邻重复项),情况稍有变化就会失效。最后两步贴近现代运维现实:配置大多采用 JSON 或 YAML,应该能够用 jq 和 yq 直接完成单值提取,而不是为此启动 Python。
步骤
- 按照下面 12 行原样创建
/root/lfcs-text/access.log。字段之间用一个空格分隔,格式为<IP> <메서드> <경로> <상태코드> <바이트>。
10.0.0.117 GET /api/users 200 512
10.0.0.118 POST /api/users 201 128
10.0.0.117 GET /api/orders 500 64
10.0.0.120 GET /healthz 200 12
10.0.0.117 GET /api/users 200 512
10.0.0.116 DELETE /api/users 403 96
10.0.0.118 GET /api/orders 500 64
10.0.0.117 POST /api/orders 201 256
10.0.0.120 GET /healthz 200 12
10.0.0.117 GET /api/users 404 32
10.0.0.115 GET /api/orders 200 1024
10.0.0.118 GET /healthz 200 12
- 只把状态码以 5 开头的行按原始顺序写入
/root/lfcs-text/errors.txt。 - 将各 IP 的字节总和写入
/root/lfcs-text/bytes_by_ip.txt,格式为<IP> <합계>,并按总和降序排列。 - 将出现次数最多的 IP 写入
/root/lfcs-text/top_ip.txt,使用一行<횟수> <IP>。 - 提取第二个字段(HTTP 方法),转为小写,去重后按字典序排序并写入
/root/lfcs-text/methods.txt。 - 将
access.log复制为/root/lfcs-text/access-v2.log,然后在副本中把路径里的/api/替换为/v2/api/。编辑前内容必须保留为/root/lfcs-text/access-v2.log.bak,而原始access.log必须保持不变。 - 按以下内容创建
/root/lfcs-text/services.json,并把tier为backend的服务replicas总和作为单个数字写入/root/lfcs-text/jq_out.txt。
{
"cluster": "homelab",
"services": [
{"name": "api", "replicas": 3, "tier": "backend"},
{"name": "web", "replicas": 5, "tier": "frontend"},
{"name": "worker", "replicas": 2, "tier": "backend"}
]
}
- 按以下内容创建
/root/lfcs-text/deploy.yaml,并在/root/lfcs-text/yq_out.txt中写入replicas=<값>和image=<값>两行。
apiVersion: apps/v1
kind: Deployment
metadata:
name: lfcs-web
namespace: lfcs
spec:
replicas: 4
template:
spec:
containers:
- name: web
image: nginx:1.27
参考
awk使用$1、$2等编号引用字段。把总和收集到关联数组中即可一次完成。sort -k2,2nr按第二个字段的数值降序排序。uniq只处理相邻的重复项。务必先排序。- 常见错误:替换目标中包含斜杠时,把分隔符改成
#等字符会更安全。
创建待分析的日志文件
按照下面 12 行原样创建 /root/lfcs-text/access.log。字段之间用一个空格分隔,格式为 <IP> <메서드> <경로> <상태코드> <바이트>。
按说明原样创建 12 行即可。字段分隔符是一个空格,行序也必须保持不变,后续步骤的结果才能正确。
只筛选 5xx 响应
只把状态码以 5 开头的行按原始顺序写入 /root/lfcs-text/errors.txt。
状态码是第四个字段。如果在整行中查找 500,字节数中含 500 的行也可能被匹配,因此应指定字段进行判断。
按 IP 汇总字节数
将各 IP 的字节总和写入 /root/lfcs-text/bytes_by_ip.txt,格式为 <IP> <합계>,并按总和降序排列。
可以在 awk 的关联数组中以 IP 为键,持续累加第五个字段。最后遍历数组输出,并按数值降序排序。
找出出现次数最多的 IP
将出现次数最多的 IP 写入 /root/lfcs-text/top_ip.txt,使用一行 <횟수> <IP>。
统计重复项前必须先排序。可直接利用计数工具输出采用“次数 值”顺序这一特点。
规范化方法列表
提取第二个字段(HTTP 方法),转为小写,去重后按字典序排序并写入 /root/lfcs-text/methods.txt。
把切取字段的工具和转换字符的工具串联起来。也可以使用排序工具的选项完成去重。
在保留原始内容的同时完成替换
将 access.log 复制为 /root/lfcs-text/access-v2.log,然后在副本中把路径里的 /api/ 替换为 /v2/api/。编辑前内容必须保留为 /root/lfcs-text/access-v2.log.bak,而原始 access.log 必须保持不变。
为就地编辑选项添加后缀,即可用该名称保留编辑前内容。替换分隔符也可以改用斜杠以外的字符。
聚合 JSON 数据
按以下内容创建 /root/lfcs-text/services.json,并把 tier 为 backend 的服务 replicas 总和作为单个数字写入 /root/lfcs-text/jq_out.txt。
先按条件筛选数组,再只收集所需字段组成数组,最后使用对数组求和的函数,即可用一行完成。
提取 YAML 值
按以下内容创建 /root/lfcs-text/deploy.yaml,并在 /root/lfcs-text/yq_out.txt 中写入 replicas=<값> 和 image=<값> 两行。
路径表达式与 jq 几乎相同。数组元素通过索引访问;不同实现可能输出引号,因此请目视检查结果。