当前位置:网站首页>NLog自定义Target之MQTT
NLog自定义Target之MQTT
2022-06-21 16:02:00 【李自提】
优质资源分享
| 学习路线指引(点击解锁) | 知识定位 | 人群定位 |
|---|---|---|
| 🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
| Python量化交易实战 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
NLog是.Net中最流行的日志记录开源项目(之一),它灵活、免费、开源
官方支持文件、网络(Tcp、Udp)、数据库、控制台等输出
社区支持Elastic、Seq等日志平台输出
实时日志需求
在工业物联网等特定场景下需要实时获取日志信息
工业物联网领域常用的是mqtt协议
那我们就使用NLog 自定义一个Target,将日志输出到MqttServer
Web通过Mqtt(websocket)实时获取日志,而不是传统的通过WebApi轮询日志
NLog自定义Target
- 官方文档介绍了如何自定义Target,可以获取到一串日志消息,无法获取结构化消息
- 需要时用使用自定义Field来完成这部分工作
///
/// Additional field details
///
[NLogConfigurationItem]
public class Field
{
///
/// Name of additional field
///
[RequiredParameter]
public string Name { get; set; }
///
/// Value with NLog rendering support
///
[RequiredParameter]
public Layout Layout { get; set; }
///
/// Custom type conversion from default string to other type
///
///
/// can be used if the renders JSON
///
public Type LayoutType { get; set; } = typeof(string);
///
public override string ToString()
{
return $"Name: {Name}, LayoutType: {LayoutType}, Layout: {Layout}";
}
}
- 重写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实时查看应用程序的日志。
- 创建WebApi项目
- 引用NLog.Target.MQTT

- 配置文件
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
<add assembly="NLog.Targets.MQTT"/>
extensions>
<targets>
<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>
<logger name="*" minlevel="Trace" writeTo="mqtt" />
rules>
- 配置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("/mqtt", options =>
{
options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol;
});
});
// ...
- Web连接MqttServer
// ...
"./jquery.min.js"</span>>
<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()));
}
});
// ...
- 输出日志
// ...
_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();
// ...
- 实时查看日志
访问index.html - 通过Mqtt客户端订阅日志

源码
在这里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 |
|---|---|
边栏推荐
- Pytest框架
- Beaucoup de sociétés de logiciels sont en fait des "blagues"
- 进击的程序员,如何提升研发效能?|直播预告
- Publicity of the first batch of shortlisted enterprises! Annual Top100 smart network supplier selection
- 实战---商场登录测试
- 机器学习模型监控(Aporia)
- Generating test reports using the unittest framework
- [learn FPGA programming from scratch -38]: Advanced - syntax - functions and tasks
- IDC Consulting: in 2022, China's relational database software market is about to change
- Elegant request retry using guzzle Middleware
猜你喜欢

Pytest framework

Cloud native monitoring system - Nightingale's recent list of new functions to solve multiple production pain points

Overseas new things | zoovu, an American AI startup, raised a new round of financing of US $169million to optimize the online "product discovery" experience for consumers

Reinforcement learning introductory project spinning up (1) installation

Design and implementation of face verification system for floating population management

网购网站(期末大作业)

Online shopping website (final assignment)

使用unittest框架生成测试报告

Pytest-- generate test report

Show you how to distinguish several kinds of parallelism
随机推荐
面向流动人口管理的人脸验证系统设计及实现 论文+答辩PPT+项目工程文件
Overseas new things | software developer "dynaboard" seed round raised US $6.6 million to develop low code platform to connect design, products and developers
qtcreator報錯解决
Pytest--生成测试报告
Unittest框架的测试日志
【观察】微软“云+端”全面创新,让混合云更简单、更灵活、更安全
Google Earth engine (GEE) - use sentinel-2 data acquisition to obtain the NDVI difference of one month ago (Guatemala as an example)
VNC Viewer方式的远程连接树莓派
Cloud native hybrid cloud network interconnection
【数学建模】MATLAB应用实战系列(九十五)-时间序列预测应用案例(附MATLAB代码)
Characteristics of a good product
机器学习模型监控(Aporia)
快速排序简单思路及程序
阿里云服务器+宝塔面板+无域名部署web项目
Yaml数据驱动演示
I do 3D restoration for the aircraft carrier: these three details are shocking
Generating test reports using the unittest framework
[learn FPGA programming from scratch -38]: Advanced - syntax - functions and tasks
一个好产品应该具备的特征
关于印发《北京市共有产权住房管理暂行办法》的通知
