import 'dart:collection'; import 'dart:convert'; import 'dart:io'; import 'package:EasyDartModule/base/logger/Logger.dart'; import 'package:dio/dio.dart'; class LokiLogger implements Logger { final LoggerConfig? _config; final Dio dio; LoggerLevel level = LoggerLevel.info; final Queue> _queue = Queue(); LokiLogger(this._config) : dio = Dio( BaseOptions(baseUrl: _config == null ? "" : _config.host, headers: { "Content-Type": "application/json", if (!identical(0, 0.0)) "Content-Encoding": "gzip" })) { dio.interceptors.add(InterceptorsWrapper( onError: (error, handler) => { //忽略异常 print("logerr:###$error###") }, )); pushLog(); } void pushLog() { Future.delayed(Duration(seconds: 3), () { //向服务器推送日志 var len = _queue.length; List logs = []; var labels; while (len != 0) { var data = _queue.removeFirst(); len--; var log = data["log"]; var lable = data["lable"]; var time = data["time"]; //合并日志 // if (lable.length == 1) { //只有默认标签 labels = lable; logs.add([time, log]); // } else { //有多个标签按照不同标签进行合并 // } } if (labels != null) { var data = jsonEncode({ "streams": [ {"stream": labels, "values": logs} ] }); //判断平台 if (identical(0, 0.0)) { dio.post("/loki/api/v1/push", data: data); } else { var zip = gzip.encode(utf8.encode(data)); dio.post("/loki/api/v1/push", data: zip); } } pushLog(); }); } @override void debug(String msg, {String? tag, String? traceId, String? spanId, String? parentSpanId, Map? lable}) { log(msg, level: LoggerLevel.debug, tag: tag, traceId: traceId, spanId: spanId, parentSpanId: parentSpanId, lable: lable); } @override void info(String msg, {String? tag, String? traceId, String? spanId, String? parentSpanId, Map? lable}) { log(msg, level: LoggerLevel.info, tag: tag, traceId: traceId, spanId: spanId, parentSpanId: parentSpanId, lable: lable); } @override void warning(String msg, {String? tag, String? traceId, String? spanId, String? parentSpanId, Map? lable}) { log(msg, level: LoggerLevel.warning, tag: tag, traceId: traceId, spanId: spanId, parentSpanId: parentSpanId, lable: lable); } @override void error(String msg, {String? tag, String? traceId, String? spanId, String? parentSpanId, Map? lable}) { log(msg, level: LoggerLevel.error, tag: tag, traceId: traceId, spanId: spanId, parentSpanId: parentSpanId, lable: lable); } void log(String msg, {required LoggerLevel level, String? tag, String? traceId, String? spanId, String? parentSpanId, Map? lable}) { if (level.level < this.level.level) { //日志等级小于设置的输出日志等级 return; } String log = "traceId=$traceId, spanId=$spanId parentSpanId=$parentSpanId tag=$tag ${level.name.toUpperCase()} $msg"; if (_config == null) { print(log); } else { //推送到loki服务器 //{_config.url} var now = DateTime.now(); // 转换为纳秒 int nanoseconds = now.microsecondsSinceEpoch * 1000; var lableMap = { "service_name": _config.serviceName, }; if (_config.lables != null) { lableMap.addAll(_config.lables!); } if (lable != null) { lableMap.addAll(lable); } _queue .add({"log": log, "lable": lableMap, "time": nanoseconds.toString()}); if (level == LoggerLevel.debug || _config.print) { print(log); } } } }