● .net core 轻量级分布式日志解决方案

未雨绸缪,公司IoT项目中可能会出现的情况:

  • 多个TCP(UDP)/MQTT服务运行在多台服务器,每台服务器产生大量零碎化的日志文件。如果要查询某台设备某个时段的日志,需要定位到设备的日志文件的服务器,然后去那台服务器拉取日志文件到本地(或在线查找)。
  • 如果把log存到数据库(mysql),按天分表,因每天产生大量的数据,导致查询很慢。

    目前项目量级较小,只想在不增加运维工作的基础上,做轻量级的实现。Exceptionless和ELK太过重量级,也不想为了存储日志单独安装MongoDB。

    目前暂定两个方案: 1、GRPC 2、Redis

GRPC+Etcd版分布式日志

这个方案是在GitHub上找到的,项目地址:https://github.com/AlexanderTar/Distilled

如果使用这种方案,高并发下GRPC也需要做负载,架构图如下:

分布式日志GRPC+Etcd版

方案可行,使用这个方案,最优部署方式为docker。但增加了很多部署和运维工作量,所以暂时放弃。

Redis MQ版分布式日志

这个方案是最先想到的,因为redis在项目中运用广泛,只需要简单的配置和增加一个redis sub端即可实现。log4net、nlog、serilog扩展起来都很简单。

分布式日志Redis版

以NLog为例,引用NLog.Targets.Redis。项目地址:https://github.com/NLog/NLog.Targets.Redis
配置说明如下:
NLog.config增加以下配置:

<extensions>
    <add assembly="NLog.Targets.Redis" />
</extensions>

<targets>
    <target name="redis" xsi:type="Redis" host="127.0.0.1" port="6379" db="0"key="device/log"dataType="channel" 
                layout="${longdate} [${level}] ${message}" />
</targets>

<rules>
    <logger name="*" minlevel="Debug" writeTo="redis" />
  </rules>

主要实现源码:https://github.com/NLog/NLog.Targets.Redis/blob/master/src/NLog.Targets.Redis/RedisTarget.cs

dataType为channel时,key作为sub/pub的topic,dataType默认为list时,log会被ListRightPush到key名的list里。

这样只需要引用NLog.Targets.Redis,再写一个Sub端(可以使用CSRedis或StackExchange.Redis)订阅消息、再通过NLog存储到本地,即可实现redis轻量级分布式日志方案。

关于redis作为MQ的性能和丢包率,可以参考下面的文章: