5 Star 5 Fork 3

Sam / NLog.Targets.MQTT

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT
slug title authors tags
NLog
NLog-MQTT
iioter
Traces
log
iot

NLog自定义Target之MQTT

NLog是.Net中最流行的日志记录开源项目(之一),它灵活免费开源

官方支持文件网络(Tcp、Udp)、数据库控制台等输出

社区支持ElasticSeq等日志平台输出

实时日志需求

在工业物联网等特定场景下需要实时获取日志信息

工业物联网领域常用的是mqtt协议

那我们就使用NLog 自定义一个Target,将日志输出到MqttServer

Web通过Mqtt(websocket)实时获取日志,而不是传统的通过WebApi轮询日志

Web-Log

NLog自定义Target

  1. 官方文档介绍了如何自定义Target,可以获取到一串日志消息,无法获取结构化消息
  2. 需要时用使用自定义Field来完成这部分工作
/// <summary>
/// Additional field details
/// </summary>
[NLogConfigurationItem]
public class Field
{
    /// <summary>
    /// Name of additional field
    /// </summary>
    [RequiredParameter]
    public string Name { get; set; }

    /// <summary>
    /// Value with NLog <see cref="NLog.Layouts.Layout"/> rendering support
    /// </summary>
    [RequiredParameter]
    public Layout Layout { get; set; }

    /// <summary>
    /// Custom type conversion from default string to other type
    /// </summary>
    /// <remarks>
    /// <see cref="System.Object"/> can be used if the <see cref="Layout"/> renders JSON
    /// </remarks>
    public Type LayoutType { get; set; } = typeof(string);

    /// <inheritdoc />
    public override string ToString()
    {
        return $"Name: {Name}, LayoutType: {LayoutType}, Layout: {Layout}";
    }
}
  1. 重写Write方法
protected override void Write(LogEventInfo logEvent)
{
    //default fields
    Dictionary<string, object> logDictionary = new()
    {
        { "timestamp", logEvent.TimeStamp },
        { "level", logEvent.Level.Name },
        { "message", RenderLogEvent(Layout, logEvent) }
    };

    //customer fields
    //这里都处理为字符串了,有优化空间
    foreach (var field in Fields)
    {
        var renderedField = RenderLogEvent(field.Layout, logEvent);

        if (string.IsNullOrWhiteSpace(renderedField))
            continue;

        logDictionary[field.Name] = renderedField;
    }

    SendTheMessage2MqttBroker(JsonConvert.SerializeObject(logDictionary));
}

使用

下面将使用Nlog.Target.MQTT,演示通过web实时查看应用程序的日志

  1. 创建WebApi项目
  2. 引用NLog.Target.MQTT

nuget

  1. 配置文件
<extensions>
    <add assembly="NLog.Web.AspNetCore"/>
    <!--<add assembly="NLog.Targets.MQTT"/>-->
    <add assembly="NLog.Targets.MQTT"/>
</extensions>

<!-- the targets to write to -->
<targets>
    <!-- MQTT Target  -->
    <target xsi:type="MQTT" name="mqtt" host="localhost" port="1883" username="UserName"  password="Password" topic="log"
            layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" >
        <field name="machine" layout="${machinename}" />
        <field name="processid" layout="${processid}" />
        <field name="threadname" layout="${threadname}" />
        <field name="logger" layout="${logger}" />
        <field name="callsite" layout="${callsite-linenumber}" />
        <field name="url" layout="${aspnet-request-url}" />
        <field name="action" layout="${aspnet-mvc-action}" />
        <field name="level" layout="${level:uppercase=true}" />
        <field name="message" layout="${message}" />
        <field name="exception" layout="${exception:format=toString}" />
    </target>
</targets>

<!-- rules to map from logger name to target -->
<rules>
    <logger name="*" minlevel="Trace" writeTo="mqtt" />
</rules>
  1. 配置MQTTServer和NLog
// ...
// NLog: Setup NLog for Dependency injection
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog();

//AddHostedMqttServer
builder.Services.AddHostedMqttServer(mqttServer =>
    {
        mqttServer.WithoutDefaultEndpoint();
    })
    .AddMqttConnectionHandler()
    .AddConnections();

//Config Port
builder.WebHost.UseKestrel(option =>
{
    option.ListenAnyIP(1883, l => l.UseMqtt());
    option.ListenAnyIP(80);
});
var app = builder.Build();

// ...
//UseStaticFiles html js etc.
app.UseStaticFiles();
app.UseRouting();

//Websocket Mqtt
app.UseEndpoints(endpoints =>
{
    //MqttServerWebSocket
    endpoints.MapConnectionHandler<MqttConnectionHandler>("/mqtt", options =>
    {
        options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol;
    });
});
// ...
  1. Web连接MqttServer
// ...    
<script src="./jquery.min.js"></script>
<script src="./mqtt.min.js"></script>
<script src="./vue.js"></script>
// ...

var client = mqtt.connect('ws://' + window.location.host + '/mqtt', options);
client.on('connect',
    function() {
        client.subscribe('log',
            function(err) {
                if (!err) {
                    console.log("subed!");
                } else {
                    alert("subed error!");
                }
            });
    });
client.on('message',
    function(topic, message) {
        if (topic === 'log') {
            if (app.logs.length > 50)
                app.logs.length = 0;
            app.logs.unshift($.parseJSON(message.toString()));
        }
    });
// ...
  1. 输出日志
// ...  
_logger.LogDebug("LogDebug!");
_logger.LogError(new Exception("Exception Message!"), "LogError!");

//new thread output log after 500ms
Thread thread = new Thread(ThreadProc);
thread.Name = "My Thread";
thread.Start();
// ...
  1. 实时查看日志 访问index.html

  2. 通过Mqtt客户端订阅日志 sublog

源码

在这里NLog.Targets.MQTT:https://github.com/iioter/NLog.Targets.MQTT

相关链接

[1] NLog.Targets.MQTT:https://github.com/iioter/NLog.Targets.MQTT

[2] IoTGateway-Doc:http://iotgateway.net/blog/NLog

[3] NLog自定义Target:https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target

交流

公众号:工业物联网网关 QQ群:712105424
wx qq
MIT License Copyright (c) 2022 dd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

NLog日志输出到MQTT 展开 收起
C# 等 3 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C#
1
https://gitee.com/iioter/NLog.Targets.MQTT.git
git@gitee.com:iioter/NLog.Targets.MQTT.git
iioter
NLog.Targets.MQTT
NLog.Targets.MQTT
main

搜索帮助