字符串处理与日志解析
运维日常大量时间花在读日志、抽字段、做统计上。Python 字符串方法配合 split、strip、replace 即可完成多数解析;复杂模式再用正则(后续章节会深入)。
常用字符串方法
line = " 192.168.1.10 - - [23/Jul/2026:10:00:01 +0800] GET /api/health HTTP/1.1 200 42 "
# 去空白
line = line.strip()
# 大小写与包含判断
path = "/api/health"
print(path.lower(), path.startswith("/api"))
# 替换与分割
status_field = "HTTP/1.1 200 42"
parts = status_field.split() # 默认按空白分割
print(parts) # ['HTTP/1.1', '200', '42']
code = int(parts[1])
按分隔符解析键值对
Nginx / 应用日志常见 key=value 或 key: value:
raw = "level=ERROR service=order-api trace_id=abc123 latency=850ms"
fields = {}
for pair in raw.split():
key, value = pair.split("=", maxsplit=1)
fields[key] = value
print(fields["level"]) # ERROR
print(fields["trace_id"]) # abc123
带空格的 value 需限制分割次数:
line = "msg=connection timeout host=10.0.0.5"
kv = {}
for item in line.split():
k, v = item.split("=", 1)
kv[k] = v
print(kv["msg"])
日志行实战:提取 IP 与状态码
LOG = (
'10.0.1.5 - deploy [23/Jul/2026:14:22:01 +0800] '
'"GET /index.html HTTP/1.1" 404 512 "-" "curl/8.0"'
)
# 简单空格分割(组合日志格式需按实际调整)
tokens = LOG.split()
client_ip = tokens[0]
# 引号内的请求行在 tokens 中,状态码在其后
request_idx = next(i for i, t in enumerate(tokens) if t.startswith('"GET'))
status_code = int(tokens[request_idx + 1])
print(f"IP={client_ip}, status={status_code}")
if status_code >= 400:
print("需关注:4xx/5xx 错误")
join 与多行拼接
error_lines = [
"[ERROR] db connection failed",
"[ERROR] retry 1/3",
"[ERROR] retry 2/3",
]
# 合并为告警正文
body = "\n".join(error_lines)
summary = f"共 {len(error_lines)} 条 ERROR\n{body}"
print(summary)
# 从列表生成 CSV 行(注意逗号转义)
hosts = ["web-01", "web,02", "db-01"]
csv_line = ",".join(f'"{h}"' if "," in h else h for h in hosts)
print(csv_line)
partition 与 strip 组合
# 解析 systemd/journal 风格
entries = [
"Jul 23 10:00:01 host systemd[1]: Started nginx.",
"Jul 23 10:00:05 host nginx[1234]: worker started",
]
for entry in entries:
# 按第一个冒号拆:前缀 | 消息体
_, _, message = entry.partition(": ")
if "error" in message.lower():
print("异常:", message)
else:
print("信息:", message.strip())
简单统计:统计状态码分布
lines = [
'10.0.0.1 "GET /a" 200',
'10.0.0.2 "GET /b" 404',
'10.0.0.1 "GET /c" 200',
'10.0.0.3 "GET /d" 500',
]
counts: dict[str, int] = {}
for line in lines:
code = line.split()[-1]
counts[code] = counts.get(code, 0) + 1
for code, n in sorted(counts.items()):
print(f"HTTP {code}: {n} 次")
小结
| 操作 | 方法 | 场景 |
|---|---|---|
| 去空白 | strip() | 读文件行尾 \n |
| 分割 | split() / split("=") | 日志字段、CSV |
| 拼接 | join() | 生成报告、命令参数 |
| 查找 | in / startswith | 过滤 ERROR 行 |
复杂正则(IP、时间戳)在系统自动化阶段会结合 re 模块展开。下一章学习 文件读写,处理真实日志文件。