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 暴露出来.所以又可以 ...
随机推荐
- SpringBoot配置全局自定义异常
不同于传统集中时Springmvc 全局异常,具体查看前面的章节https://www.cnblogs.com/zwdx/p/8963311.html 对于springboot框架来讲,这里我就介绍一 ...
- 搭建docker registry (htpasswd 认证)
1,拉取docker registry 镜像 docker pull registry 2,创建证书存放目录 mkdir -p /home/registry 3,生成CA证书Edit your /et ...
- 01javascript基础
1.JavaScript:直接写入 HTML 输出流 实例:(只能在 HTML 输出中使用 document.write.如果在文档加载后使用该方法,会覆盖整个文档) <!DOCTYPE htm ...
- 【mysql处理远程登陆授权及数据库迁移备份问题】
Database changedMariaDB [mysql]> grant all PRIVILEGES on mysql.* to root@'%' identified by '123'; ...
- 【c学习-9】
/*内存练习*/ #include #include//引入内存分配库文件 int main(){ double* x; //定义整型指针和double指针 int* y; x=(double*)ma ...
- laravel 基础 --内置函数
简介 Laravel 自带了一系列 PHP 辅助函数,很多被框架自身使用,如果你觉得方便的话也可以在代码中使用它们. https://laravelacademy.org/post/8967.html ...
- ZooKeeper(3)-内部原理
一. 节点类型 二. Stat结构体 1)czxid-创建节点的事务zxid 每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID. 事务ID是ZooKee ...
- P1049 装箱问题
装箱问题 题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱内,使 ...
- 使用 -命令行-给-python-安装whl文件,
whl文件下载到哪个位置,命令行就切入到哪里: 我的在D盘目录下,所以命令行切进D盘(CD):方式如下: 列出<用户目录>下的目录(dir): 因为我安装了2个版本的python所以给py ...
- 4269: 再见Xor
4269: 再见Xor 链接 分析: 和SGU 275唯一不同的就是需要求出次小值,那么异或出最大值的所有元素中,找到最小的,去除即可. 代码: #include<bits/stdc++.h&g ...