NET 的 ELK 监控方案
NET 的 ELK 监控方案
https://www.jianshu.com/p/3c26695cfc38
背景就不多说了,谁家没有个几个十系统在跑啊。如何监控这几十个系统的运行状况,对于非运营人员来说,太TM五花八门了。。
背景就不多说了,谁家没有个几个十系统在跑啊。如何监控这几十个系统的运行状况,对于非运营人员来说,太TM五花八门了。。。
名词
ELK = ElashticSearch + LogStash + Kibana
Lucene 是搜索引擎,搜索引擎的特点就不用说了吧。但是使用起来不是太直观。
ElashticSearch (简称 ES) 是基于 Luncene 的。它提供了一套易于使用的语法,关键一点:它可以很方便的透过 http 来操作。
Logstash 主要是用来分析(处理)日志的(不知道这样讲妥不妥)。通过指定 Logstash 的 Output ,可以把处理的结果写到 ES 中。
Kibana 是用于制定各种报表的。
也就是说ELK中的: E(存储),L(处理), K(展示)
ELK 需要 JAVA 运行环境,但不代表它是 JAVA世界的专用工具。
由来已久的门派对立
做为.NET开发人员,对 JAVA工具 多多少是有点抵触的,能不用就不用,能少用就少用,实在没办法在查资料。。。我也是这样过来的。
log4net 相信大家都在用,所以我的最开始的方案是写个 log4net 的Appender 扩展, 从 AppenderSkeleton 派生一个 ESAppender , 代码很简单,不在这里展示了。
但是写日志的速度有点快(每天生产1.5G左右的文本日志,还是简化过的。。。), ES 的状态不确定,可能会导致数据丢失,或是ES处理不及时,拖程序的后腿等。搜集日志是小事,拖程序后腿就是大事了。。。
所以,最终还是老老实的使用 ELK 这一套完整的方案:
扩展log4net 写 json 格式的日志, logstash 搜集这些日志。。。
如何整合 ELK 到.NET 项目中
正如上面所说的原因,此处用 log4net 写json 格式的文本日志,因为 logstash 的配置语法是我们这些“基于界面”的,“头脑简单”的程序员不能理解的(太麻烦,真心疼JAVA程序员,每天面对那么多天书一样的配置); json 格式的日志,在 logstash 中,是会被按原样写入到 ES中的,省去那一堆不能理解的 filter 的 配置。
扩展 log4net ,从 LayoutSkeleton 派生一个 JsonLayout
///
///
///
public class JsonLayout : LayoutSkeleton
{
public override string ContentType
{
get
{
return "application/json";
}
}
public JsonLayout()
{
this.IgnoresException = false;
}
public override void ActivateOptions()
{
//
}
public override void Format(TextWriter writer, LoggingEvent evt)
{
if (!evt.Level.DisplayName.Equals("ES"))
return;
var info = evt.LocationInformation;
var exTitle = "";
var exStack = "";
if (evt.ExceptionObject != null)
{
exTitle = evt.ExceptionObject.Message;
exStack = evt.ExceptionObject.StackTrace;
}
var msg = new JsonMsg()
{
ESIndexPrefix = ESIndex.ESIndexPrefix,
Logger = evt.LoggerName,
//@Class = info.ClassName,//发布后,获取不到该参数
//File = info.FileName,//发布后,获取不到该参数
//Line = info.LineNumber,//发布后,获取不到该参数
//Method = info.MethodName,//发布后,获取不到该参数
CreatedOn = evt.TimeStamp,
App = evt.Domain,
//Level = evt.Level.Name, 无用,点硬盘
Data = evt.MessageObject,
ExTitle = exTitle,
ExStack = exStack
};
var json = JsonConvert.SerializeObject(msg);
writer.WriteLine(json);
}
}
IgnoresException = false 是忽略 Exception 的输出,否则,会在 json 字符串后面追加一串字符串用于描述异常信息。
JsonMsg.cs
internal class JsonMsg
{
[JsonProperty("i")]
public string ESIndexPrefix
{
get;
set;
}
[JsonProperty("L")]
public string Logger
{
get;
set;
}
[JsonProperty("On")]
public DateTime CreatedOn
{
get;
set;
}
[JsonProperty("D")]
public object Data
{
get;
set;
}
[JsonProperty("Ex")]
public string ExStack
{
get;
set;
}
[JsonProperty("ExT")]
public string ExTitle
{
get;
set;
}
public string App
{
get;
set;
}
}
添加一个 helper
public static class LogHelper
{
private static readonly Type DeclareType = typeof(LogHelper);
private static readonly Level Level = new Level(130000, "ES");
public static void ES(this ILog logger, AnalyzeLogItem data, Exception ex = null)
{
logger.Logger.Log(DeclareType, Level, data, ex);
}
}
这段代码中自定义了一个叫 "ES" 的 LEVEL, 还定义了一个很简单的扩展函数,使用自定义的参数: AnalyzeLogItem, 这个 AnalyzeLogItem 就是要用于分析的数据,比如执行时间,执行是成功还是失败,响应请求还是发送请求等等,依自己的需求而定。
然后修改一下 log4net.config
<appender-ref ref="InfoFileAppender" />
<appender-ref ref="ErrorFileAppender" />
<appender-ref ref="FatalFileAppender" />
<appender-ref ref="DebugFileAppender" />
<appender-ref ref="WARNFileAppender" />
<appender-ref ref="ESAppender" />
注意第一段(ESAppender)中的 layout type="XXX.JsonLayout,XXX", 修改为自己的包名。
另外,不能使用 UTF-8 。
因为在 WINDOWS 下,log4net 生产的UTF-8 日志文件默认是带BOM 的,logstash 这种JAVA世界的工具,太理想化,好像压根就没有考虑过 BOM 的问题,从而导至数据丢失严重(有多严重?几百万日记只分析出来个零头)。。。
如果logstash 控制台中出现以下这样的字眼,那就八九不离十了:
11:17:54.244 [[main]<file] ERROR logstash.codecs.json - JSON parse error, original data now in message field {:error=>#<LogStash::Json::ParserError: Unexpected character ('???' (code 65279 / 0xfeff)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
最后,在你的 AssemblyInfo 中添加:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
配置 logstash
上面说了,我们直接生成 json 格式的日志记录,就是为了避免复杂的 logstash 配置。 所以这里的配置很简单:
input{
file {
path => [
"D:/Web/Api1/W1/logES/.",
"D:/Web/Api1/W2/logES/."
]
codec => "json"
}
}
output {
elasticsearch {
hosts => ["10.89.70.70:9600"]
index => "%{i}-%{+YYYY.MM.dd}"
}
}
path 节点中的两行即是要分析的日志路径,多条用逗号分开。
hosts 即 ES 的地址(用内网地址比外网地址快不止一个数量级)
index 即动态的 index 名称, 其中的 i (%{i}) 即产生的 json log 中的 i (也就是上文中的 JsonMsg 中的 ESIndexPrefix). 这样做的好处是可以将不同的系统的日志数据按 index 分类。
Kibana
kibana 的配置就不说了,太简单, 这里只上一张最终的日志分析出来的效果图:
作者:gruan
链接:https://www.jianshu.com/p/3c26695cfc38
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
NET 的 ELK 监控方案的更多相关文章
- docker监控方案实践(cadvisor+influxdb+grafana)
一.概要 1.1 背景 虚拟化技术如今已经非常热门,如果你不知道什么是虚拟化,那你应该了解虚拟机.虚拟化技术如同虚拟机一样,用于将某些硬件通过软件方式实现"复制",虚拟出" ...
- 前端性能监控方案window.performance 调研(转)
1. 业界案例 目前前端性能监控系统大致为分两类:以GA为代表的代码监控和以webpagetest为代表的工具监控. 代码监控依托于js代码并部署到需监控的页面,手动计算时间差或者使用浏览器的的API ...
- OpenStack 虚拟机监控方案确定
Contents [hide] 1 监控方案调研过程 1.1 1. 虚拟机里内置监控模块 1.2 2. 通过libvirt获取虚拟机数据监控. 2 a.测试openstack的自待组件ceilomet ...
- Redis监控方案
Redis 监控最直接的方法当然就是使用系统提供的 info 命令来做了,你只需要执行下面一条命令,就能获得 Redis 系统的状态报告. redis-cli info 内存使用 如果 Redis 使 ...
- 斌哥的 Docker 进阶指南—监控方案的实现
过去的一年中,关于 Docker 的话题从未断过,而如今,从尝试 Docker 到最终决定使用 Docker 的转化率依然在逐步升高,关于 Docker 的讨论更是有增无减.另一方面,大家的注意力也渐 ...
- ELK监控系统nginx / mysql慢日志
ELK监控系统nginx / mysql慢日志 elasticsearch logstash kibana ELK监控系统nginx日志 1.环境准备 centos6.8_64 mini IP:192 ...
- 一张表搞懂各种 Docker 监控方案 - 每天5分钟玩转 Docker 容器技术(86)
前面我们已经介绍了ps/top/stats.Sysdig.Weave Scope.cAdvisor 和 Prometheus 多种容器监控工具和方案,是时候做一个比较了.下面将从五个方面来对比它们之间 ...
- 详解k8s一个完整的监控方案(Heapster+Grafana+InfluxDB) - kubernetes
1.浅析整个监控流程 heapster以k8s内置的cAdvisor作为数据源收集集群信息,并汇总出有价值的性能数据(Metrics):cpu.内存.网络流量等,然后将这些数据输出到外部存储,如Inf ...
- cassandra 监控方案评估
摘要 最开始做cassandra monitor 方案的选型时,主要是从cassandra 本身入手,后来发现cassandra运行在JVM上,所有的metrics都是通过JMX 暴露出来.所以又可以 ...
随机推荐
- aix下oracle 12.1.0.2 asmca不能打开的故障
因为要添加一个新的13T磁盘组,所以决定通过asmca处理. 结果输入asmca之后,没有反应,前后两天都是如此. 第三天,IBM的存储工程师已经把心的MPIO挂上,如果还无法操作,只能使用asmcm ...
- 转:Spring Boot应用中的异常处理
引自:https://www.cnblogs.com/yangfanexp/p/7616570.html 楼主前几天写了一篇“Java子线程中的异常处理(通用)”文章,介绍了在多线程环境下3种通用的异 ...
- Asp.Net Core使用Nginx实现反向代理
---恢复内容开始--- 前两篇文章介绍了使用Docker作为运行环境,用Nginx做反向代理的部署方法,这篇介绍一下使用Nginx配合.Net Core运行时直接在Liunx上裸奔的方法. 一.安装 ...
- JZOJ 5934. 列队
Description Sylvia是一个热爱学习的女孩子. 在平时的练习中,他总是能考到std以上的成绩,前段时间,他参加了一场练习赛,众所周知,机房是一个 的方阵.这 ...
- 用状态机表示SFC中的并行分支
过去一直认为,状态机表示SFC会不会是任务复杂化,这次简单实验了一下,感觉还可以.请看下面的控制. 在SFC中,A和B是一对并行分支,汇合后转移到C分支中,怎么了用状态机表示呢?这里我们在状态机里分别 ...
- windows环境下安装scrapy框架报错问题--最快捷有效的解决方案
windows在执行如下命令,安装scrapy的过程中会报错: pip install scrapy 报错分析: windows环境下,会出现如下错误: 1.提示的错误是编译环境的问题,字面意思看需要 ...
- echarts实用小技巧,控制字符串长度,限定整数等
限定横坐标文本字符长度 xAxis : [ axisLabel:{ formatter: function (value) { var maxlength=6; if (value.length> ...
- python集合、函数实例
集合 1.list ==>允许重复的集合,可修改 2.tuple ==>允许重复的集合,不可修改 3.dict ==> 4.set ==>不允许重复的集合,相当于不可重复的列表 ...
- java元注解(注解在注解上的注解)
//ElementType.TYPE 给类.接口.枚举上使用 @Target(ElementType.TYPE)//给注解进行注解,表示该注解可以用在什么地方 //@Retention(Retenti ...
- 搭建cvs服务器
http://zhangjunhd.blog.51cto.com/113473/78595 http://www.cnblogs.com/lee/archive/2008/10/22/1317226. ...