.Net Core(.NET6)中接入Log4net和NLog进行日志记录
一、接入Log4net
1.按日期和大小混合分割日志
nuget包安装
log4net
Microsoft.Extensions.Logging.Log4Net.AspNetCore
配置文件
配置文件内容为
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<!-- Define some output appenders -->
<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">
<!-- value="logs/log.log"-->
<file value="logs/" />
<!--追加日志内容-->
<appendToFile value="true" /> <!--防止多线程时不能写Log,官方说线程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--可以为:Once|Size|Date|Composite-->
<!--Composite为Size和Date的组合-->
<rollingStyle value="Composite" /> <!--当备份文件时,为文件名加的后缀-->
<datePattern value="yyyyMMdd/"log.log"" /> <!--日志最大个数,都是最新的-->
<!--rollingStyle节点为Size时,只能有value个日志-->
<!--rollingStyle节点为Composite时,每天有value个日志-->
<maxSizeRollBackups value="20" /> <!--可用的单位:KB|MB|GB-->
<maximumFileSize value="3MB" /> <!--置为true,当前最新日志文件名永远为file节中的名字-->
<staticLogFileName value="false" /> <!--输出级别在INFO和ERROR之间的日志-->
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ALL" />
<param name="LevelMax" value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
<!--OFF:0-->
<!--FATAL:FATAL-->
<!--ERROR: ERROR,FATAL-->
<!--WARN: WARN,ERROR,FATAL-->
<!--INFO: INFO,WARN,ERROR,FATAL-->
<!--DEBUG: INFO,WARN,ERROR,FATAL-->
<!--ALL: DEBUG,INFO,WARN,ERROR,FATAL-->
<priority value="ALL"/> <level value="INFO"/>
<!--使用上面配置的那个规则,ref指定上面的规则名称-->
<appender-ref ref="rollingAppender" />
</root>
</log4net>
程序引入,Program.cs文件增加
builder.Logging.AddLog4Net("Configs/log4net.Config"); //Nuget引入:
//1.Log4Net
//2.Microsoft.Extensions.Logging.Log4Net.AspNetCore
builder.Services.AddControllersWithViews();
程序使用
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
} public IActionResult Index()
{
_logger.LogInformation($"{this.GetType()},info,接口访问");
_logger.LogError($"{this.GetType()},error,接口访问错误");
return View();
}
}
效果:
2.日志分级独立文件夹显示
上面全部等级的日志信息都显示在同一个文件夹,如果想找error信息,如果日志量大并不好查找,所以把error的独立出来。
增加配置信息
完整配置文件
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<!-- Define some output appenders -->
<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">
<!-- value="logs/log.log"-->
<file value="logs/" />
<!--追加日志内容-->
<appendToFile value="true" /> <!--防止多线程时不能写Log,官方说线程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--可以为:Once|Size|Date|Composite-->
<!--Composite为Size和Date的组合-->
<rollingStyle value="Composite" /> <!--当备份文件时,为文件名加的后缀-->
<datePattern value="yyyyMMdd/"log.log"" /> <!--日志最大个数,都是最新的-->
<!--rollingStyle节点为Size时,只能有value个日志-->
<!--rollingStyle节点为Composite时,每天有value个日志-->
<maxSizeRollBackups value="20" /> <!--可用的单位:KB|MB|GB-->
<maximumFileSize value="3MB" /> <!--置为true,当前最新日志文件名永远为file节中的名字-->
<staticLogFileName value="false" /> <!--输出级别在INFO和ERROR之间的日志-->
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ALL" />
<param name="LevelMax" value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<!-- error日志 -->
<appender name="errorAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs/" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Composite" />
<datePattern value="yyyyMMdd/"error.log"" />
<maxSizeRollBackups value="20" />
<maximumFileSize value="3MB" />
<staticLogFileName value="false" />
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ERROR" />
<param name="LevelMax" value="ERROR" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
<!--OFF:0-->
<!--FATAL:FATAL-->
<!--ERROR: ERROR,FATAL-->
<!--WARN: WARN,ERROR,FATAL-->
<!--INFO: INFO,WARN,ERROR,FATAL-->
<!--DEBUG: INFO,WARN,ERROR,FATAL-->
<!--ALL: DEBUG,INFO,WARN,ERROR,FATAL-->
<priority value="ALL"/> <level value="INFO"/>
<!--使用上面配置的那个规则,ref指定上面的规则名称-->
<appender-ref ref="rollingAppender" />
<appender-ref ref="errorAppender" />
</root>
</log4net>
运行,日志打印效果
3.log4net日志写入数据库
这里以log4net写入Mysql为示例
引入Nuget包
MySql.Data
数据库日志表脚本
CREATE TABLE `logs` (
`log_id` bigint NOT NULL AUTO_INCREMENT,
`app_name` varchar(100) NOT NULL,
`log_date` datetime NOT NULL,
`thread` varchar(100) NOT NULL,
`level` varchar(50) NOT NULL,
`logger` varchar(255) NOT NULL,
`message` varchar(1000) NOT NULL,
`exception` varchar(2000) NOT NULL,
PRIMARY KEY (`log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
增加配置信息
完整配置文件
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<!-- Define some output appenders -->
<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">
<!-- value="logs/log.log"-->
<file value="logs/" />
<!--追加日志内容-->
<appendToFile value="true" /> <!--防止多线程时不能写Log,官方说线程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--可以为:Once|Size|Date|Composite-->
<!--Composite为Size和Date的组合-->
<rollingStyle value="Composite" /> <!--当备份文件时,为文件名加的后缀-->
<datePattern value="yyyyMMdd/"log.log"" /> <!--日志最大个数,都是最新的-->
<!--rollingStyle节点为Size时,只能有value个日志-->
<!--rollingStyle节点为Composite时,每天有value个日志-->
<maxSizeRollBackups value="20" /> <!--可用的单位:KB|MB|GB-->
<maximumFileSize value="3MB" /> <!--置为true,当前最新日志文件名永远为file节中的名字-->
<staticLogFileName value="false" /> <!--输出级别在INFO和ERROR之间的日志-->
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ALL" />
<param name="LevelMax" value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<!-- error日志 -->
<appender name="errorAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs/" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Composite" />
<datePattern value="yyyyMMdd/"error.log"" />
<maxSizeRollBackups value="20" />
<maximumFileSize value="3MB" />
<staticLogFileName value="false" />
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ERROR" />
<param name="LevelMax" value="ERROR" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<!--SqlServer形式-->
<!--log4net日志配置:http://logging.apache.org/log4net/release/config-examples.html -->
<appender name="mysqlAppender" type="log4net.Appender.AdoNetAppender">
<!--日志缓存写入条数 设置为0时只要有一条就立刻写到数据库-->
<bufferSize value="0" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="server=127.0.0.1;database=test_db;user=root;pwd=123456;SslMode=none" />
<commandText value="INSERT INTO logs(app_name,log_date, thread, `level`, logger, message, `exception`)VALUES(@app_name,@log_date, @thread,@log_level, @logger, @message, @exception);" />
<parameter>
<parameterName value="@app_name" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout" >
<conversionPattern value="api" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="1000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
<!--OFF:0-->
<!--FATAL:FATAL-->
<!--ERROR: ERROR,FATAL-->
<!--WARN: WARN,ERROR,FATAL-->
<!--INFO: INFO,WARN,ERROR,FATAL-->
<!--DEBUG: INFO,WARN,ERROR,FATAL-->
<!--ALL: DEBUG,INFO,WARN,ERROR,FATAL-->
<priority value="ALL"/> <level value="INFO"/>
<!--使用上面配置的那个规则,ref指定上面的规则名称-->
<appender-ref ref="rollingAppender" />
<appender-ref ref="errorAppender" />
<appender-ref ref="mysqlAppender" />
</root>
</log4net>
效果
如果是SqlServer
引入Nuget包
System.Data.SqlClient
connectionType写上SqlServer的连接类型
<connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
连接字符串处改成SqlServer的连接字符串即可。
二、接入NLog
1.写文本日志
引入Nuget包
NLog.Web.AspNetCore
配置文件内容
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="NLog\all_log.log"> <targets>
<!--文件日志,archive相关参数:文件拆分,每100M拆分一个新文件-->
<target xsi:type="File"
name="all_log"
fileName="NLog\${shortdate}\${uppercase:${level}}.log"
layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}"
archiveFileName="NLog\${shortdate}\${uppercase:${level}}${shortdate}.{####}.log"
archiveNumbering="Rolling"
archiveAboveSize="10485760"
concurrentwrites="true"
maxArchiveFiles="100"
/> </targets> <rules>
<!-- add your logging rules here -->
<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。-->
<logger name="*" minlevel="Trace" writeTo="all_log" />
</rules>
</nlog>
程序引入NLog
程序使用:
结果:
2.过滤日志
有一些组件自带了日志的,像上面的Microsoft.*开头就是.Net Core自带的,我们想屏蔽掉一些dll的日志怎么弄呢
修改配置规则
效果:
3.自定义日志文件名
很多时候我们想把比较重要的功能的日志单独写到一个日志文件方便排查,NLog提供了单独打日志文件的功能
修改配置文件,用一个属性接收,属性由程序端传来:${event-properties:filename}
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="NLog\all_log.log"> <targets>
<!--文件日志,archive相关参数:文件拆分,每100M拆分一个新文件-->
<target xsi:type="File"
name="all_log"
fileName="NLog\${shortdate}\${event-properties:filename}${shortdate}.log"
layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}"
archiveFileName="NLog\${shortdate}\${event-properties:filename}${shortdate}.{####}.log"
archiveNumbering="Rolling"
archiveAboveSize="10485760"
concurrentwrites="true"
maxArchiveFiles="100"
/>
</targets> <rules>
<!-- add your logging rules here -->
<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。--> <!--Skip Microsoft logs and so log only own logs-->
<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->
<!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->
<logger name="Microsoft.*" minlevel="Trace" final="true" />
<logger name="*" minlevel="Trace" writeTo="all_log" />
</rules>
</nlog>
封装一个LogHelper.cs
public class LogHelper
{
private static Logger logger= LogManager.GetCurrentClassLogger();
public static void Info(string message,string fileName="INFO")
{
//把文件名通过属性传输
logger.WithProperty("filename", fileName).Info(message);
}
public static void Debug(string message, string fileName = "DEBUG")
{
logger.WithProperty("filename", fileName).Debug(message);
}
public static void Error(string message, string fileName = "Error")
{
logger.WithProperty("filename", fileName).Error(message);
}
public static void Warn(string message, string fileName = "Warn")
{
logger.WithProperty("filename", fileName).Warn(message);
} }
程序调用:
效果:
4.NLog写入数据库
这里以Mysql为例
引入Nuget包
MySql.Data
sql表脚本还是上面Log4net一样。
配置
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="NLog\all_log.log"> <targets>
<!--文件日志,archive相关参数:文件拆分,每100M拆分一个新文件-->
<target xsi:type="File"
name="all_log"
fileName="NLog\${shortdate}\${event-properties:filename}${shortdate}.log"
layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}"
archiveFileName="NLog\${shortdate}\${event-properties:filename}${shortdate}.{####}.log"
archiveNumbering="Rolling"
archiveAboveSize="10485760"
concurrentwrites="true"
maxArchiveFiles="100"
/> <target name="mysql_log" xsi:type="Database"
dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"
connectionString="server=127.0.0.1;database=test_db;user=root;pwd=123456;SslMode=none"
commandText="INSERT INTO logs(app_name,log_date, thread, `level`, logger, message, `exception`)VALUES(@app_name,@log_date, @thread,@log_level, @logger, @message, @exception);">
<parameter name="@app_name" layout="AspNetCoreNlog" />
<parameter name="@log_date" layout="${date}" />
<parameter name="@thread" layout="${threadid}" />
<parameter name="@log_level" layout="${level}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@message" layout="${message}" />
<parameter name="@exception" layout="${exception:tostring}" />
</target> </targets> <rules>
<!-- add your logging rules here -->
<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。--> <!--Skip Microsoft logs and so log only own logs-->
<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->
<!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->
<logger name="Microsoft.*" minlevel="Trace" final="true" />
<logger name="*" minlevel="Trace" writeTo="all_log" />
<logger name="*" minlevel="Trace" writeTo="mysql_log" />
</rules>
</nlog>
效果:
如果写SqlServer
引入Nuget包
System.Data.SqlClient
dbProvider="System.Data.SqlClient.SqlConnection, System.Data.SqlClient"
connectionString改为SqlServer的连接字符串即可
5.Log4Net对比NLog
Log4Net对比NLog来说性能相差无几
但是个人推荐用NLog,原因有
1.配置简单
2.可以很方便的自定义日志文件名,这个对于核心模块单独打日志太方便了。
.Net Core(.NET6)中接入Log4net和NLog进行日志记录的更多相关文章
- Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例
本文目录 1. Net下日志记录 2. NLog的使用 2.1 添加nuget引用NLog.Web.AspNetCore 2.2 配置文件设置 2.3 依赖配置及调用 ...
- [转]asp.net5中使用NLog进行日志记录
本文转自:http://www.cnblogs.com/sguozeng/articles/4861303.html asp.net5中使用NLog进行日志记录 asp.net5中提供了性能强大的日志 ...
- asp.net5中使用NLog进行日志记录
asp.net5中提供了性能强大的日志框架,本身也提供了几种日志记录方法,比如记录到控制台或者事件中等,但是,对大部分程序员来说,更喜欢使用类似log4net或者Nlog这种日志记录方式,灵活而强大. ...
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
EF Core使用SQL调用返回其他类型的查询 假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...
- ASP.NET Core 集成测试中通过 Serilog 向控制台输出日志
日志是程序员的雷达,不仅在生产环境中需要,在集成测试环境中也需要,可以在持续集成失败后帮助定位问题.与生产环境不同,在集成测试环境中使用控制台输出日志更方便,这样可以通过持续集成 runner 执行 ...
- 转:使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)
http://www.cnblogs.com/kyo-yo/archive/2010/06/11/use-log4net-to-log-exception.html 在前端时间开发的时候由于需要将异常 ...
- log4net.NoSql +ElasticSearch 实现日志记录
前言: 前两天在查找如何扩展log4net的日志格式时找到一个开源项目Log4net.NoSql,它通过扩展Appender实现了把日志输出到ElasticSearch里面.顺藤摸瓜,发现涉及的项目还 ...
- .NET Core(.NET6)中gRPC使用
一.简介 简单解析一下gRPC,gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架. 特点: 跨语言 内容protobuf格式(比json体积小),网络传输快 使用HT ...
- Asp.Net Core WebApi中接入Swagger组件(初级)
开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...
随机推荐
- nginx开发:ngx_sprintf
格式化参数%系列,如果误用的话,轻则输出不正确,重则nginx可能core. 1. 格式: %{格式描述}{输出类型描述}{数据类型描述} 2. 数据类型描述: V:字符串,对应ngx_str_t * ...
- 汉字编码(【Unicode】 【UTF-8】 【Unicode与UTF-8之间的转换】 【汉字 Unicode 编码范围】【中文标点Unicode码】【GBK编码】【批量获取汉字UNICODE码】)
Unicode与UTF-8互转(C语言实现):http://blog.csdn.net/tge7618291/article/details/7599902 汉字 Unicode 编码范围:http: ...
- java命令-(学习)jstack 工具
一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...
- laravel操作Redis排序/删除/列表/随机/Hash/集合等方法全解
Song • 3563 次浏览 • 0 个回复 • 2017年10月简介 Redis模块负责与Redis数据库交互,并提供Redis的相关API支持: Redis模块提供redis与redis.con ...
- 什么是Segue
Storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue对象(简称Segue) Segue的属性 每一个Segue对象,都有3个属性唯一标识@property (non ...
- js 用 void 0 替代 undefined
underscore 源码没有出现 undefined,而用 void 0 代替之.为什么要这么做?我们可以从两部分解读,其一是 undefined 哪里不好了,你非得找个替代品?其二就是替代品为毛要 ...
- C语言中的typedef跟define的区别
今天用C语言练习时涉及到了typedef和define的使用问题,那么他们的区别是啥?这种情况下为什么要用typedef?哪种情况下为什么要用define呢? 学习C的时候的你是否考虑过这个问题呢? ...
- K8s多节点部署+负载均衡+keepalived ——囊萤映雪
K8s多节点部署+负载均衡+keepalived --囊萤映雪 1.多节点master2 部署 2.负载均衡部署+keepalived 1.多节点master2部署: #从master01节点上拷贝证 ...
- Shell编程之循环语句与echo的用法
Shell编程之循环语句与echo的用法 目录 Shell编程之循环语句与echo的用法 一.echo用法 1. echo常用选项 2. 常用的转义字符 3. 特殊符号%.#的用法 二.循环语句 1. ...
- 【发点感慨】我的cnblogs的文章被爬到了别的网站,阅读量比在cnblogs上还要高
近期我写了挺多VictoriaMetrics的文章,在搜索相关文章的时候发现,我的文章被别的网站爬去了: 写写技术文章就是无偿分享给别人看的,越多人看到越多人受益,这一点没毛病. 但是: 爬了别人的文 ...