介绍
这个项目叫做 TomatoLog, 托管在 GitHub 项目上, 使用的 License 是 MIT, 请放心试用, 目前该项目主要由我个人维护, 还有两位大神加入了协作者中.
** TomatoLog.Server 基于 .NETCore2.2
** TomatoLog.Client 基于 netstandard2.0
项目主页以及组件说明
https://github.com/lianggx/TomatoLog
** 中文说明文档:
https://github.com/lianggx/TomatoLog/blob/master/README_Zh-cn.md
** 服务器版本:
https://github.com/lianggx/TomatoLog/releases
** 客户端组件 v1.0.2:
- TomatoLog.Common(公共代码库)
- TomatoLog.Client(客户端基础实现类)
- TomatoLog.Client.Redis(Reids 客户端, 基于 https://www.nuget.org/packages/CSRedisCore/ 客户端)
- TomatoLog.Client.RabbitMQ(RabbitMQ 客户端)
** 存储插件
- TomatoLog.ToFile(写入文件)
- TomatoLog.ToMongoDB(写入 MongoDB)
- TomatoLog.ToES(写入 Elasticsearch)
演示代码位于项目目录 Examples 下.
1. TomatoLog 是干什么的
TomatoLog 来源于业务发展的实际需要, 在项目中, 我们的做法是使用 NLog 将日志写入本地, 然后通过 Kafka 将日志发送到 ES, 剩下的就是怎么对日志进行挖掘, 展示的问题了. 如果需要进行扩展, 就需要自行安装其它工具对日志进行操作了; 实际上, 通过这一系列的操作, 你需要用到的是 NLog+Kafka+ELK, 这一系列高度灵活的框架都需要手动安装和调试, 这个过程让小白窒息, 让老司机迷路. 家里的领导常说, 能一行代码解决的问题, 就不要搞那么复杂, 高扩展性是很重要, 但是易用性也是非常的重要的.
那么, TomatoLog 就是来解决这个问题, TomatoLog 对日志的处理不敢说强大, 但可能是 .NETCore 平台上最简单易用的日志集成组件, 具有高度灵活的使用方式, 完全可定义配置的可扩展性, 使用异步写入, 业务完全解耦, 客户端的一键安装, 一行代码上传日志, 目前 TomatoLog 没有实现登录验证, 需要注意使用环境访问权限问题. 下面就使用和功能进行展开介绍.
1.1 TomatoLog 的系统架构
千言万语不如一张图
从图中可以看出, TomatoLog 包含三个基础组件, 他们分别是: 客户端, 数据流控制器, 服务器; TomatoLog 本身不做存储优化, 其通过定义一个简单的数据流协议实现日志的收集到存储, 这个数据流协议在系统中被定义成为一个实体对象模型 LogMessage, 位于程序集 TomatoLog.Common.dll 中:
- namespace TomatoLog.Common.Utilities
- {
- public class LogMessage
- {
- public int EventId { get; set; }
- public string ProjectName { get; set; }
- public string ProjectLabel { get; set; }
- public LogLevel LogLevel { get; set; }
- public string Version { get; set; }
- public string IP { get; set; }
- public string[] IPList { get; set; }
- public string MachineName { get; set; }
- public string ThreadId { get; set; }
- public string ProcessId { get; set; }
- public string ProcessName { get; set; }
- public DateTime Timestamp { get; set; }
- public string UserName { get; set; }
- public string ErrorMessage { get; set; }
- public string StackTrace { get; set; }
- public object Extra { get; set; }
- }
- }
上面的所有字段都可以使用配置进行跟踪, 可选择将哪些信息写入到日志中, 其中, 关于服务器主机信息, 客户端会自动采集主机信息, 无需手动传入, 如果这些信息还是不能满足业务需要, 没关系, 上面的实体类中还定义了扩展字段 "Extra" , 该字段接收一切对象, 当然, 最好就是使用 JSON 对象, 这也比较科学.
服务端在接收到日志信息后, 将会根据服务配置对日志进行清洗, 筛选, 然后是存入指定存储介质中, 如果日志触发了服务配置的警报, 服务器还将自动发送警报通知. 下面, 就从使用开始, 体验 TomatoLog 带来的便利性和舒适的日志操作体验.
2. 部署日志采集服务器
TomatoLog 日志服务器目前发布的版本是: 1.0.2(目前处于起步阶段, 版本迭代速度可能比较快), 位于: https://github.com/lianggx/TomatoLog/releases, 直接下载 TomatoLog-1.0.2.zip, 解压, 得到文件如下:
此压缩包仅包含程序运行所必须文件, 所以必须要在目标机器上安装 .NETCore SDK 2.2+, 你可以简单的使用命令行或者其它你熟悉的托管程序去启动 TomatoLog.Server , 比如可以使用 IIS,Supervisord,Docker(需要自行打包); 在本示例中, 我选择使用命令行启动它.
在上面文件夹中, 我们在第一次使用的使用, 只需要关注两个文件即可, 他们分别是 appsettings.(Development/Production).JSON (服务配置文件) 和 TomatoLog.Server.dll (服务主程序文件), 首先, 看看服务配置文件
2.1 服务器配置
- {
- "Logging": {
- "IncludeScopes": false,
- "LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
- }
- },
- "TomatoLog": {
- "Cache-Redis": null,
- "Config": {
- "SysConfig": "Config/SysConfig.json",
- "ProConfig": "Config/ProConfig.json"
- },
- "Storage": {
- "Type": "ToFile", //ToFile/ToES/ToMongoDB
- "File": "D:\\TomatoLog\\Storage",
- "ES": "http://127.0.0.1:9200/",
- "MongoDB": "mongodb://root:root@127.0.0.1:27017/admin",
- "Others":null
- },
- "Flow": {
- "Type": "RabbitMQ", // Redis/RabbitMQ/Kafaka
- "Redis": {
- "Connection": null,
- "Channel": "TomatoLogChannel"
- },
- "RabbitMQ": {
- "Host": "127.0.0.1",
- "Port": 5672,
- "UserName": "root",
- "Password": "123456",
- "vHost": "TomatoLog",
- "Exchange": "TomatoLog-Exchange",
- "ExchangeType": "direct",
- "QueueName": "TomatoLog-Queue",
- "RouteKey": "All",
- "Channels": 1 // RabbitMQ client instance quantity
- },
- "Kafka": null
- }
- }
- }
服务配置文件包含一个主节点 TomatoLog, 下面内置 4 个子节点, 分别是:
** Cache-Redis
该节点指示在服务对日志进行筛选, 清洗的过程中, 会将策略写入缓存, 默认情况下, 策略被写入本地缓存, 如果指定分布式缓存, 则使用分布式缓存, 强烈推荐配置分布式缓存, 在服务进行重启或者更新的时候, 策略将可以被持续计数.
** Config
此节点下配置了两个系统配置文件, 分别是 SysConfig 和 ProConfig, 这代表着服务对日志的清洗, 过滤, 警报的配置, 无需改动这两个文件, 因为我们提供了更友好的 web 控制台进行配置, 后面会有介绍.
** Storage
此节点非常重要, 决定了日志的存储介质, 首先是 Type , 可以指定 //ToFile/ToES/ToMongoDB 中的任意一种, 目前, TomatoLog 的存储是通过接口实现的插件进行反射调用, 所有的存储插件都存放在程序目录下的 Plugins 目录下
如果你认为有必要重写插件, 在存储前做一些其它的工作的话, 你还可以通过实现 TomatoLog.Common 程序集中定义的 ILogWriter 接口, 然后将插件放入 Plugins 目录下, 覆盖 //ToFile/ToES/ToMongoDB 中的一种插件, 设置 Type 指定为你实现的插件名称即可. 或者, 你还可以自己实现一个全新的插件, 如实现了一个将日志存储到 Redis 的插件 ToRedis, 则将设置 "Type":"ToRedis", 并且将 ToRedis 需要的配置写入到节点 Others 中自行读取实现, 因为 ILogWriter 的默认实现 LogWriter 抽象类的构造参数接收了一个实体对象
- public class StorageOptions
- {
- public StorageType Type { get; set; }
- public string File { get; set; }
- public string ES { get; set; }
- public string MongoDB { get; set; }
- public string Others { get; set; }
- }
ToRedis 插件可以通过继承 LogWriter 获得该配置节点.
** Flow
Flow 节点表示数据流的选择, 准备支持 3 中数据流, 但是因为精力有限, 特别是对 Kafka 也不是很熟悉, 目前只实现了 Redis/RabbitMQ 两种方式, 目前来看, 基本够用, Flow 节点下面的子节点就是对数据流节点的配置, 选择 Redis 就配置 Flow.Redis , 如果使用 RabbitMQ, 则配置 Flow.RabbitMQ 节点.
2.2 启动服务
在服务配置完成后, 就可以使用 dotnet TomatoLog.Server.dll 启动服务程序, 可以看到, TomatoLog 侦听的端口为: 20272.
在浏览器中输入网址: http://localhost:20272/, 查看 Web 控制台
目前可以看到, 因为没有产生日志, 所以首页是一片空白, 但是没有关系, 下面介绍另一个强大的功能: 配置
2.3 系统全局配置
控制台上还有两个导航按钮 "Config","Project", 点击查看 Config
** 警报配置
Enable: 是否启用警报通知, 值为: true/false
Report stage(Seconds): 警报周期, 时间: 秒
Trigger threshold: 触发阈值, 和 Report stage(Seconds) 配合使用, 即 xx 秒内发生 x 次后 发送通知, 并重置计数器
Monitor Levels: 警报级别, 支持 Trace;Debug;Information;Warning;Error;Critical;None, 多个 Level 以 分号进行分隔.
** 短信通知配置
此通知配置非常强大, 基于 Http 请求, 不只局限于 SMS, 所有可以被 Http 请求的网关地址都可以配置到这里, 通知内容支持系统变量 (见下面附录)
** 邮件通知配置
可以配置邮件通知 (推荐测试服启用, 跟踪 BUG), 邮件主题和内容支持系统变量 (见下面附录), 支持 html 邮件内容
** 附录: 系统变量
上面列出了系统支持的所有内置变量, 可在 SMS 和 Email 通知中配置使用, 系统变量的使用如上图, 必须使用大括号进行包围.
2.4 针对项目的单独配置
除了系统全局配置, TomatoLog 还支持针对每个项目进行独立通知设置, 方便项目管理和跟踪, 项目通知配置和全局配置一致,
项目通知配置将覆盖全局配置 (如果有配置的话)
3. 客户端的使用演示
首先, 建立一个演示项目 Example , 该项目为 Asp.NETCore WebApi 项目.
3.1 安装客户端组件
接下来在 Nuget 上搜索包 TomatoLog , 由于服务器配置了使用数据流类型为 RabbitMQ, 这里选择安装 TomatoLog.Client.RabbitMQ-1.0.2
3.2 将客户端注入服务中
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddSingleton<ITomatoLogClient, TomatoLogClientRabbitMQ>(factory =>
- {
- var options = this.Configuration.GetSection("TomatoLog").Get<EventRabbitMQOptions>();
- var client = new TomatoLogClientRabbitMQ(options);
- return client;
- });
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
- }
上面的代码中, 读取了客户端配置文件节点 TomatoLog 并反序列化为 EventRabbitMQOptions 配置对象, 然后使用该配置对 TomatoLogClientRabbitMQ 进行了初始化, 关于 EventRabbitMQOptions 在配置文件中的配置如下:
- "TomatoLog": {
- "LogLevel": "Information", // 写入日志级别, 大于此级别的日志都将被吸入数据流中
- "ProjectLabel": "Example", // 项目标签, 可为 null
- "ProjectName": "Example", // 项目名称, 必须
- "SysOptions": { // 是否自动采集主机信息, 可配置
- "EventId": true,
- "IP": true,
- "IPList": true,
- "MachineName": true,
- "ProcessId": true,
- "ProcessName": true,
- "ThreadId": true,
- "Timestamp": true,
- "UserName": true
- },
- "Tags": null, // 项目 Tag , 可 null
- "Version": "1.0.0", // 当前项目版本号, 可为 null
- "Exchange": "TomatoLog-Exchange", // RabbitMQ 中配置的交换机名称
- "ExchangeType": "direct", // RabbitMQ 交换机类型
- "Host": "RabbitMQ Host", // RabbitMQ 主机地址
- "Password": "RabbitMQ Passworrd", // RabbitMQ 连接密码
- "Port": 5672, // RabbitMQ 连接端口
- "QueueName": "RabbitMQ Queue", // RabbitMQ 日志队列名称
- "RouteKey": "Route Key", // RabbitMQ Route Key, 根据 ExchangeType 动态设置
- "UserName": "RabbitMQ UserName", // RabbitMQ 连接用户名
- "vHost": "RabbitMQ vHost" // RabbitMQ 连接的 vHost
- }
这段配置看似复杂, 其实非常简单, 所有的一切都可以自由配置, 在程序中, 只需要一行代码初始化即, 非常方便.
3.3 将异常写入数据流
在异常发生的时候, 将异常写入数据流的操作非常简单, 就像下面的代码
** 首先引入命名空间
using TomatoLog.Client.Extensions;
** 处理异常:
- public ActionResult<IEnumerable<string>> Get()
- {
- try
- {
- throw new NotSupportedException("Media Type");
- }
- catch (Exception ex)
- {
- ex.AddTomatoLogAsync();
- }
- return new string[] { "value1", "value2" };
- }
我们上面说过, 能一行代码做完的事情就不要搞复杂了, 使用 ex.AddTomatoLogAsync(); 就可以将日志写入到数据流中了, 非常的简洁高效. 如果需要写入自定义的日志信息, 可以通过依赖注入获得日志客户端对象, 然后写入自定义日志, 比如
- public async Task<ActionResult<IEnumerable<string>>> Get()
- {
- await logClient.WriteLogAsync(1029, LogLevel.Warning, "Warning Infomation", "Warning Content", new { LastTime = DateTime.Now, Tips = "Warning" });
- return new string[] { "value1", "value2" };
- }
3.4 查看服务端收集日志
可以看到, 上面我们一共写入了两条日志, 分类为 Error 和 Warning, 查看文件系统上, 在项目 Example 目录下, 有两个文件
点击列表进入查看, 点击单行日志的任意位置, 还可以查看详细信息
3.5 自定义日志查看列
还支持对日志的搜索和分页, 搜索语法支持以下三种类型:
** ToFile 存储时: 支持直接搜索字符串
** ToMongoDB 存储时: 支持 MongoDB 搜索语法
** ToES 存储时: 支持 Elasticsearch 语法
分页支持: 当前日志超过 100 行时 (默认显示最新 100 条日志), 自动出现 Previous/Next 分页导航按钮
结束语
TomatoLog 设计的基本原则是开放, 高可扩展, 自由, 易用, 通过简单的封装, 让任何一个开发人员都能在 3 分钟内投入使用, 享受 TomatoLog 带来的便利性, TomatoLog 只做简单的存储, 可以看到, 如果选择存储到 MongoDB 或者 ES 中的时候, 大家还可以通过其它的日志挖掘工具对日志进一步的搜索和处理.
如果您觉得这个项目还不错, 请点击 star , 如果希望加入此项目, 成为贡献者, 请留下您的 GitHub 账号, 通过开源, 让 .NETCore 生态越来越好.
喔~ 对了, 欢迎报告 BUG!
广州. NET 微软技术俱乐部
来源: https://www.cnblogs.com/viter/p/10644509.html