logger-loki
v1.0.3
Published
js client log upload to loki
Maintainers
Readme
需求
目标与范围
- 同时支持浏览器与 Node.js 环境,统一 API。
- 兼容 Loki
api/v1/push接口,支持多租户与鉴权。 - 可发布到 npm,提供 ESM、CJS 与类型定义产物。
核心功能
- 初始化配置:
endpoint、labels、level、interval、batchMaxBytes、headers、orgId、timeout。 - 日志接口:
debug、info、warn、error,与console行为一致,可选择拦截console.*。 - 控制台输出可开关;低于配置级别的日志不输出且不上传。
- 发送策略:立即发送或定时批量;按时间窗口与大小阈值触发
flush。 - Label 管理:支持静态与动态标签;
level、sessionId、env、host等。 - 浏览器传输:
fetch优先,页面卸载使用sendBeacon兜底。 - Node 传输:
http/https原生或可插拔适配器;支持代理、TLS、超时。 - 失败处理:重试与指数退避、最大重试次数、网络离线缓存与恢复。
- 速率限制:每秒最大请求数/字节数,支持采样与丢弃策略(最旧/最低级别优先)。
- 队列限制:最大队列长度,溢出策略可配置;提供
flush()、close()。 - 回调接口:
onError、onDrop、onRetry、onFlush、beforeSend、transform、shouldSend。 - 安全与清洗:敏感字段屏蔽,安全序列化(循环引用处理、深度限制)。
- 时间戳精度:毫秒与纳秒可选,满足 Loki 要求。
- 多租户与鉴权:
X-Scope-OrgID、Basic Auth、Token 头支持。 - 环境探测:SSR/浏览器自动识别,禁用不支持的传输能力。
可扩展性
- 序列化器与 redactor 可插拔,支持结构化日志与自定义格式。
开发者体验
- JSDoc 注释,良好 IntelliSense。
- 轻量无重度依赖,可 tree-shake;严格最小化依赖。
- 构建产物:
esm、cjs、types;完善exports与browser字段。 - 配置校验与合理默认值;简洁易用的初始化 API。
- 调试模式与内部指标:队列长度、重试次数、丢弃计数,可通过
getStats()获取。
测试与质量
- 单元测试覆盖核心路径,模拟 Loki 接口与错误场景。
- 端到端测试:浏览器(Headless)与 Node 环境验证发送、卸载发送与离线恢复。
- 提供最小示例:浏览器与 Node 快速开始。
性能与限制
- 单次 push 大小限制(默认 1MB,可配置),防止超大请求失败。
- 控制序列化与压缩开销,保证低延迟与低内存占用。
- 避免主线程阻塞(浏览器);Node 环境下支持并发控制。
文档
- 快速开始、API 参考、配置说明、最佳实践、错误码与故障排查。
验收标准
- 在浏览器与 Node 环境成功向 Loki
api/v1/push发送日志,Grafana 可查询到。 - 支持按时间间隔批量上传与立即发送;页面卸载事件能可靠发送(
sendBeacon兜底)。 - 网络故障时日志缓存并在恢复后重传;重试策略按配置生效。
- 低于配置的日志级别不输出且不上传;标签按配置正确分类。
使用步骤
安装
- 通过 npm 安装:
npm i logger-loki - Node 使用
require('logger-loki');浏览器可通过<script>直接引入本包提供的构建产物。 - 如需本地示例,运行:
npm run serve,在浏览器访问http://localhost:8080/。
Node.js 使用
const { init } = require('logger-loki'); // 对应本仓库入口 lib/index.js
// 初始化
const logger = init({
endpoint: 'http://localhost:3100/loki/api/v1/push',
labels: { app: 'demo', svc: 'web' },
level: 'info', // 低于该级别的日志将被忽略(不输出也不上传)
interval: 2000, // 批量窗口;设为 0 表示每次调用立即上传
orgId: 'tenant-1', // 多租户头;也可自定义到 headers/customHeaders
headers: { 'X-From': 'node' }, // 基础请求头
customHeaders: { 'X-Trace-Id': 'abc123' } // 自定义请求头;优先级最高
});
// 日志调用
logger.info('user login', { id: 123 });
logger.warn('slow query', { ms: 480 });
logger.error('unexpected error', new Error('boom'));
// 手动发送队列(若 interval>0)
await logger.flush();
// 关闭并清理(会尝试最后一次发送)
await logger.close();浏览器使用
<!-- 直接引入构建产物,挂载为 window.LokiLogger -->
<script src="./lib/index.js"></script>
<script>
// 初始化
const logger = window.LokiLogger.init({
endpoint: 'http://localhost:3100/loki/api/v1/push',
labels: { app: 'browser-demo' },
level: 'info',
interval: 2000,
orgId: 'demo-tenant',
headers: { 'X-From': 'browser' },
customHeaders: { 'X-Trace-Id': 'abc123' },
autoFlushOnUnload: true // 页面卸载前自动 flush,内部使用 sendBeacon/fetch keepalive
});
// 日志调用
logger.debug('debug info'); // 若 level=info,debug 会被忽略
logger.info('info message', { t: Date.now() });
logger.warn('warn message');
logger.error('error message');
// 控制台拦截(可选),拦截后 console.* 输出也会上传
logger.hookConsole();
console.warn('UI lag');
logger.unhookConsole();
// 手动发送队列与查看统计
logger.flush();
const stats = logger.getStats(); // { queuedStreams, queuedBytes, retrying }
console.log('stats:', stats);
</script>关键配置
endpoint:Lokiapi/v1/push地址labels:静态标签,如{ app: 'demo' };内部自动附加env与sessionIdlevel:debug|info|warn|error,低于阈值的日志被忽略interval:批量窗口毫秒;0表示每次调用立即上传headers:基础请求头,优先级低于customHeaderscustomHeaders:自定义请求头,优先级最高;可覆盖Authorization等orgId:多租户;会注入请求头X-Scope-OrgIDtimeout(Node):HTTP 请求超时时间hookConsole:是否拦截console.*并同时上传- Hook:
shouldSend、transform、beforeSend、onError、onDrop、onRetry、onFlush
示例与测试
- 浏览器示例:
npm run serve后访问http://localhost:8080/,页面位于example/index.html - 单元测试:
npm test(见tests/basic.test.js)
