使用NLog把日志写入数据库并按天自动分表
前言
最近用Asp.net Core开发程序的时候
因为时间的关系,就没有过多的去关注日志方面的功能
都是直接用系统的ILogger先记录着,然后看日志的时候就先在命令行看日志
在开发阶段没有什么问题,但是到了系统上线后
总不能一直在命令行看日志。总要把日志输出到一个方便查看的地方
开始
直接引用NLog.Web.AspNetCore组件
然后编写nlog.config文件放到程序的根目录
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Info"
internalLogFile="${basedir}\..\Log\${date:format=yyyyMM}\WMSAPI-internal.txt">
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- 定义变量当前应用程序名称 -->
<variable name="AppName" value="WMSAPI" />
<!-- 日志输出目标 -->
<targets>
<!-- 把日志记录到文件(通用) -->
<target xsi:type="File" name="allfile" fileName="${basedir}\..\Log\${date:format=yyyyMM}\${var:AppName}-all-${shortdate}.txt" encoding="UTF-8"
archiveFileName="${basedir}\..\Log\WMSAPI-all-${shortdate}.{#}.txt" archiveAboveSize="10485760"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
<!-- 把日志输出到文件 (Asp.Net Core) -->
<target xsi:type="File" name="ownFile-web" fileName="${basedir}\..\Log\${date:format=yyyyMM}\${var:AppName}-own-${shortdate}.txt" encoding="UTF-8"
archiveFileName="${basedir}\..\Log\WMSAPI-own-${shortdate}.{#}.txt" archiveAboveSize="10485760"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}| body: ${aspnet-request-posted-body}" />
<!--把日志输出到控制台 -->
<target xsi:type="Console" name="lifetimeConsole" layout="${level:truncate=4:tolower=true}: ${logger}[0]${newline} ${message}${exception:format=tostring}" />
<!--把日志输出到数据库 -->
<target xsi:type="Database" name="database" dbProvider="MySqlConnector.MySqlConnection, MySqlConnector">
<connectionString>${configsetting:item=ConnectionStrings.GDbContext}</connectionString>
<install-command ignoreFailures="true">
<text>
<!-- NOTE: call LogManager.Configuration.Install(new InstallationContext()); to execute this query. -->
CREATE TABLE IF NOT EXISTS `Sys_Log${date:format=yyyyMMdd}` (
`Id` bigint NOT NULL AUTO_INCREMENT,
`CreateTime` datetime NOT NULL,
`AppName` varchar(50) NOT NULL,
`Level` varchar(50) NOT NULL,
`Logger` varchar(1024) NULL DEFAULT NULL,
`Msg` text NULL,
`Exception` text NULL,
`UserId` varchar(50) NULL DEFAULT NULL,
`Url` varchar(1024) NULL DEFAULT NULL,
`IP` varchar(255) NULL DEFAULT NULL,
PRIMARY KEY (`Id`) USING BTREE
);
</text>
</install-command>
<commandText>
INSERT INTO `Sys_Log${date:format=yyyyMMdd}`(`CreateTime`, `AppName`, `Level`, `Logger`, `Msg`, `Exception`, `UserId`, `Url`, `IP`) VALUES (@CreateTime, @AppName, @Level, @Logger, @Msg, @Exception, @UserId, @Url, @IP);
</commandText>
<parameter name="@CreateTime" layout="${longdate}" />
<parameter name="@AppName" layout="${var:AppName}" />
<parameter name="@Level" layout="${level}" />
<parameter name="@Logger" layout="${logger}" allowDbNull="true" />
<parameter name="@Msg" layout="${message}" allowDbNull="true" />
<parameter name="@Exception" layout="${exception:format=tostring}" allowDbNull="true" />
<parameter name="@UserId" layout="${aspnet-user-claim:userId}" allowDbNull="true" />
<parameter name="@Url" layout="${aspnet-request-url}" allowDbNull="true" />
<parameter name="@IP" layout="${aspnet-request-ip}" allowDbNull="true" />
</target>
</targets>
<!-- 日志输出规则 -->
<rules>
<!--All logs, including from Microsoft-->
<!--<logger name="*" minlevel="Trace" writeTo="allfile" />-->
<!--Output hosting lifetime messages to console target for faster startup detection -->
<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web, database" final="true" />
<logger name="Microsoft.EntityFrameworkCore.Model.Validation" maxlevel="Error" final="true" />
<!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="System.Net.Http.*" maxlevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web, database" />
</rules>
</nlog>
可以看到我们定义了4个输出目标,前2个是文件,一个是控制台,一个是数据库
输出到文件基本定义
fileName:输出的文件名
archiveFileName,archiveAboveSize这两个参数是当文件超过archiveAboveSize大小的时候
就对文件进行分割,然后分割的文件名是用archiveFileName来定义
layout就是日志文件内容,其中以${}闭合的内容就是NLog提供的参数
具体可以参考
https://nlog-project.org/config/?tab=layout-renderers
<target xsi:type="File" name="ownFile-web" fileName="${basedir}\..\Log\${date:format=yyyyMM}\${var:AppName}-own-${shortdate}.txt" encoding="UTF-8"
archiveFileName="${basedir}\..\Log\WMSAPI-own-${shortdate}.{#}.txt" archiveAboveSize="10485760"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}| body: ${aspnet-request-posted-body}" />
输出到数据库基本定义
dbProvider:使用数据库组件
connectionString:连接字符串
install-command:安装脚本(用这个来自动创建表)
commandText:日志插入到数据表的脚本
parameter:插入脚本的参数
<target xsi:type="Database" name="database" dbProvider="MySqlConnector.MySqlConnection, MySqlConnector">
<connectionString>${configsetting:item=ConnectionStrings.GDbContext}</connectionString>
<install-command ignoreFailures="true">
<text>
<!-- NOTE: call LogManager.Configuration.Install(new InstallationContext()); to execute this query. -->
CREATE TABLE IF NOT EXISTS `Sys_Log${date:format=yyyyMMdd}` (
`Id` bigint NOT NULL AUTO_INCREMENT,
`CreateTime` datetime NOT NULL,
`AppName` varchar(50) NOT NULL,
`Level` varchar(50) NOT NULL,
`Logger` varchar(1024) NULL DEFAULT NULL,
`Msg` text NULL,
`Exception` text NULL,
`UserId` varchar(50) NULL DEFAULT NULL,
`Url` varchar(1024) NULL DEFAULT NULL,
`IP` varchar(255) NULL DEFAULT NULL,
PRIMARY KEY (`Id`) USING BTREE
);
</text>
</install-command>
<commandText>
INSERT INTO `Sys_Log${date:format=yyyyMMdd}`(`CreateTime`, `AppName`, `Level`, `Logger`, `Msg`, `Exception`, `UserId`, `Url`, `IP`) VALUES (@CreateTime, @AppName, @Level, @Logger, @Msg, @Exception, @UserId, @Url, @IP);
</commandText>
<parameter name="@CreateTime" layout="${longdate}" />
<parameter name="@AppName" layout="${var:AppName}" />
<parameter name="@Level" layout="${level}" />
<parameter name="@Logger" layout="${logger}" allowDbNull="true" />
<parameter name="@Msg" layout="${message}" allowDbNull="true" />
<parameter name="@Exception" layout="${exception:format=tostring}" allowDbNull="true" />
<parameter name="@UserId" layout="${aspnet-user-claim:userId}" allowDbNull="true" />
<parameter name="@Url" layout="${aspnet-request-url}" allowDbNull="true" />
<parameter name="@IP" layout="${aspnet-request-ip}" allowDbNull="true" />
</target>
可以看到我们这里通过install-command编写的建表SQL脚本
表名是Sys_Log${date:format=yyyyMMdd},这样我们创建出来的表名就是Sys_Log20211103(根据日间格式化)
但是NLog不会自动帮我们运行这个建表脚本,要我们在代码里调用
LogManager.Configuration.Install(new InstallationContext());
这个方法,他才会运行install-command里面的脚本。
因为我们是按天来进行分表的,那就相当于我每天要运行一次
LogManager.Configuration.Install(new InstallationContext());
所以我就写了一个定时的HostedService。来每天自动运行NLog的Install方法
public class LogHostedService : IHostedService, IAsyncDisposable
{
private Timer RunTimer { get; set; }
public Task StartAsync(CancellationToken cancellationToken)
{
LogManager.Configuration.Install(new NLog.Config.InstallationContext());//启动后执行一次
this.RunTimer = new Timer(LogInstall, null, DateTime.Now.AddDays(1).Date - DateTime.Now, TimeSpan.FromDays(1));
return Task.CompletedTask;
}
public void LogInstall(object state)
{
LogManager.Configuration.Install(new NLog.Config.InstallationContext());//每天0点执行一次
}
public Task StopAsync(CancellationToken cancellationToken)
{
this.RunTimer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public ValueTask DisposeAsync()
{
return this.RunTimer.DisposeAsync();
}
}
这样就会在系统启动时和每天的0点的时候,创建当天的日志表
然后我们的插入语句INSERT INTO Sys_Log${date:format=yyyyMMdd}
就会自动插入到每天的日志表里面
代码启用NLog
我们在Program.cs文件里使用UseNLog()启用NLog组件
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseNLog();
然后在Startup.cs里启用HostedService来定时创建每天的日志表
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<LogHostedService>();//每天自动创建日志表
}
成果

使用NLog把日志写入数据库并按天自动分表的更多相关文章
- Laravel 上传excel,读取并写入数据库 (实现自动建表、存记录值
<?php namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminat ...
- logback日志写入数据库(mysql)配置
如题 建议将日志级别设置为ERROR.这样可以避免存储过多的数据到数据中. 1 logback 配置文件(如下) <?xml version="1.0" encoding ...
- mySql---logback日志写入数据库(mysql)配置
如题 建议将日志级别设置为ERROR.这样可以避免存储过多的数据到数据中. 1 logback 配置文件(如下) <?xml version="1.0" encoding ...
- 怎样借助log4j把日志写入数据库中
log4j是一个优秀的开源日志记录项目.我们不仅能够对输出的日志的格式自定义,还能够自定义日志输出的目的地,比方:屏幕.文本文件,数据 库,甚至能通过socket输出.本节使用MySQ ...
- 支持MySql的数据库自动分表工具DBShardTools发布
支持MySql的数据库自动分表工具DBShardTools发布 前段时间参与了公司的一个项目,这个项目的特点是数据量.访问量都比较大,考虑使用数据库水平分表策略,Google了大半天,竟然没有找到分表 ...
- MySQL 高可用:mysql+mycat实现数据库分片(分库分表)
本文引用于http://blog.csdn.net/kk185800961/article/details/51147029 MySQL 高可用:mysql+mycat实现数据库分片(分库分表) 什么 ...
- 使用log4j将日志写入数据库并发送邮件
参考: 快速了解Log4J 1.log4j的初始配置 参考该问的配置即可完整的实现写入数据库及发送邮件的功能 a.写入数据库需要配置相应的jar包,数据库类型不同,请使用指定的数据库配置,该文仅限于o ...
- 使用log4j让日志写入数据库
之前做的一个项目有这么个要求,在日志管理系统里,需要将某些日志信息存储到数据库里,供用户.管理员查看分析.因此我就花了点时间搞了一下这一功能,各位请看. 摘要:我们知道log4j能提供强大的可配置的记 ...
- log4j日志写入数据库
# log4j写入数据库 ### 前言-----------------------------log4j是写入日志到控制台和文件很常见,但是写入到数据库不多见.做性能测试写入到数据库,统计方便些. ...
随机推荐
- 美团分布式定时调度框架XXL-Job基本使用
一:XXL JOB 基本使用 1.官方中文文档:https://www.xuxueli.com/xxl-job/ 2.基本环境: 2.1:git下载项目, 执行xxl-job数据库初始化脚本 2.2: ...
- P6624-[省选联考2020A卷]作业题【矩阵树定理,欧拉反演】
正题 题目链接:https://www.luogu.com.cn/problem/P6624 题目大意 \(n\)个点的一张图,每条边有权值,一棵生成树的权值是所有边权和乘上边权的\(gcd\),即 ...
- AT4119-[ARC096C]Everything on It【斯特林数,容斥】
正题 题目链接:https://www.luogu.com.cn/problem/AT4119 题目大意 一个集合\(S=\{k\in[1,n]\cup N\}\),它的所有子集作为元素组成的集合中要 ...
- 【MySQL数据库】MySQL5.7安装与配置、可视化工具安装和破解
软件下载 Mysql5.7地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip 安装步骤 下载后会得到zip ...
- 从产业链、架构和技术三个层面,看元宇宙与RPA的发展关系
你可能还不知道,元宇宙也将带动RPA高速发展 一文读懂RPA如何赋能元宇宙,虚拟空间更需要RPA无处不在 三个层面,解读元宇宙如何利好RPA行业发展 从产业链.架构和技术三个层面,看元宇宙与RPA的发 ...
- 新一代容器平台ACK Anywhere,来了
5G.AR.AIoT 等场景在推动新一代云架构的演进,而容器重塑了云的使用方式. 近日,阿里云容器服务全面升级为ACK Anywhere,让企业在任何需要云的地方,都能获得一致的容器基础设施能力. 早 ...
- java 文档自动生成的神器 idoc
写文档 作为一名开发者,每个人都要写代码. 工作中,几乎每一位开发者都要写文档. 因为工作是人和人的协作,产品要写需求文档,开发要写详细设计文档,接口文档. 可是,作为一个懒人,平时最讨厌的一件事情就 ...
- NOI 2021 部分题目题解
最近几天复盘了一下NOI 2021,愈发发觉自己的愚蠢,可惜D2T3仍是不会,于是只写前面的题解 Day1 T1 可以发现,每次相当于将 \(x\to y\) 染上一种全新颜色,然后一条边是重边当且仅 ...
- CF992E Nastya and King-Shamans(线段树二分+思维)
这是一道卡常好题 从160s卡到36s qwq 由于题目设计到原数组的单点修改,那么就对应着前缀和数组上的区间加. 很显然能想到用线段树来维护这么个东西. 那么该如果求题目要求的位置呢 我们来看这个题 ...
- 01_vue实例_数据_方法
创建实例 var vm = new Vue( { //选项 } ) 数据对象 // 我们的数据对象 var data = { a: 1 } // 该对象被加入到一个 Vue 实例中 var vm = ...