示例说明
日志直写检索引擎的痛点是每行一次 HTTP 请求的开销与突发流量的冲击。传输器的缓冲机制把日志行攒成批量请求,bufferLimit 与 flushInterval 分别按数量与时间触发冲刷;拒绝的批次按 retryLimit 重试,网络抖动不丢数据。索引按日期前缀轮转,历史索引只读收缩,热查询只打新索引。
技术要点
- 缓冲批量冲刷摊薄请求开销
- 拒绝批次按上限自动重试
- error 事件兜住传输层故障
代码解读
传输器配置批量大小 500、5 秒冲刷窗口并自动确保索引模板存在;logger 的格式链先打时间戳再转 JSON,defaultMeta 让每行都带服务与环境标签。三行日志演示不同级别的结构化字段形态。stderr 直写避免传输器故障再用 logger 造成递归。
使用建议
缓冲意味着故障窗口可能丢最后一批,关键路径日志要有本地文件双写。字段命名遵守 ECS 规范便于聚合。分片数按写入吞吐规划。
代码示例
import winston from 'winston';
import 'winston-elasticsearch';
const esTransport = new winston.transports.Elasticsearch({
index: 'svc-logs',
indexPrefixTemplate: 'svc-logs',
clientOpts: { node: 'http://elastic:9200' },
buffering: true,
bufferLimit: 500,
flushInterval: 5_000,
ensureIndexTemplate: true,
retryLimit: 3,
});
export const logger = winston.createLogger({
level: 'info',
defaultMeta: { service: 'search-api', env: process.env.NODE_ENV },
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' }),
winston.format.json(),
),
transports: [esTransport],
});
logger.info('query served', { query: 'blue shoes', tookMs: 18, hits: 231 });
logger.warn('slow query', { query: 'umbrella', tookMs: 950 });
logger.error('upstream timeout', { shard: 's-3', retry: 1 });
esTransport.on('error', (err) => {
process.stderr.write('es transport failed: ' + err.message + '\n');
});