Exceptionless(二) - 使用进阶
作者:markjiang7m2
原文地址:https://www.cnblogs.com/markjiang7m2/p/11100563.html
官網地址:http://letyouknow.net
在上一篇文章Exceptionless - .Net Core開源日志框架中就說到如何對Exceptionless進行本地化部署,不過我也跟大家說了,僅限于能用的階段。那今天我就繼續來探討一下如何再用好。
后臺運行服務
上次我就是直接通過腳本 Start-ElasticSearch.ps1啟動ElasticSearch和Kibana服務,但是大家也能看到,服務是運行起來了,同時還有兩個命令窗口,如果一個不小心把窗口關閉了,服務也就關閉了,而且一旦服務器重啟了,這兩個服務也不會自動啟動。
我這里先暫時把Kibana扔一邊去,來看看ElasticSearch服務。ElasticSearch是直接有腳本支持將ElasticSearch安裝為Windows服務,在后臺運行。
就是這個 elasticsearch-service.bat腳本,支持一下參數:
install?將Elasticsearch作為服務安裝
remove?刪除已安裝的Elasticsearch服務(并在啟動時停止服務)
start?啟動Elasticsearch服務(如果已安裝)
stop?停止Elasticsearch服務(如果啟動)
manager?啟動一個GUI來管理已安裝的服務
安裝
命令行,進入到 elasticsearch-service.bat所在的目錄,然后執行下面的腳本
啟動
這個時候我們可以直接在瀏覽器訪問 9200端口看看服務是否正常
繼續使用上次部署好的Exceptionless
(如何使用IIS部署Exceptionless Web服務,請看Exceptionless - .Net Core開源日志框架)
因為我是直接用回之前ElasticSearch的節點,而且也沒有清空數據,所以可以直接用之前注冊的賬號重新登錄
也是成功的,ElasticSearch服務已經運行在后臺了。
自動啟動
通過ElasticSearch提供的GUI可以將服務設置為自動啟動
將 StartupType選擇為 Automatic,再點擊OK保存
這樣,即使服務器重啟了,我們的ElasticSearch服務也會自動啟動
其實,有玩過Windows服務的朋友一定知道,上面的一些操作在Windows自帶的服務管理器也能完成
同時按下"WIN+R" 打開服務的命令運行窗口。在服務運行窗口中輸入services.msc
在列表中也可以找到ElasticSearch服務,雙擊打開屬性窗口,跟剛剛的GUI操作就是一樣的了
再看Web.config
上次我只是改了Exceptionless的端口設置,其實這里面還包含很多配置信息
<add name="RedisConnectionString" connectionString="localhost:6379,abortConnect=false" /> <add name="ElasticSearchConnectionString" connectionString="http://localhost:9200" />官方是建議大家安裝和配置Redis,這樣就可以同時運行多個實例,并且重啟不會丟失狀態,強烈建議在Linux上運行Redis 3.0+版本, RedisConnectionString就是Redis的連接串
ElasticSearchConnectionString是必須的,指向ElasticSearch服務,如果有多個節點,則使用 ,隔開
<!-- Exceptionless Web 基礎Url --> <add key="BaseURL" value="http://localhost:50001/#" /> <!-- 是否啟用ssl --> <add key="EnableSSL" value="false" /> <!-- Dev: Use this mode when debugging. (Outbound emails will not be sent) QA: Use this mode when deployed to staging. (Outbound emails restricted) Production: Use this mode when deployed to production. --> <add key="WebsiteMode" value="Production" /> <!-- Controls whether users can signup. --> <add key="EnableAccountCreation" value="true" /> <!-- Controls whether daily summary emails are sent --> <add key="EnableDailySummary" value="true" />網站模式WebsiteMode主要是限制郵件發送,默認值是Dev,不發送郵件,所以我這里設置為Production
郵件發送配置,記得跟上面的WebsiteMode一起配置
<add key="SmtpHost" value="smtp.qq.com" /> <add key="SmtpPort" value="25" /> <add key="SmtpEncryption" value="SSL" /> <add key="SmtpUser" value="xxx@qq.com" /> <add key="SmtpPassword" value="xxx" />我在案例中使用的是自己的qq郵箱。我在qq郵箱中已經開啟了SMTP服務,并且也通過一個控制臺應用程序測試可以發送郵件。
但是在Exceptionless這里一樣的設置就是不行,在Web中點擊發送郵件,log記錄錯誤如下:
ERROR MailMessageJob Job run "MailMessageJob" failed: 由于意外的數據包格式,握手失敗。 System.IO.IOException: 由于意外的數據包格式,握手失敗。
清除Url
我們現在使用的Url都會帶有 #!,例如
可以按照下面步驟清除字符 #!
首先保證你的IIS是否已經安裝了重寫模塊,可通過雙擊IIS中的?模塊查看是否包含了?RewriteModule
更新?Web.config文件
釋放出在?system.webServer中的?rewrite節點
刪除?BaseURL值中的?/#
注釋了在?system.webServer\modules中的?<removename="RewriteModule"/>標簽
修改?app.config.77fc9ddd679d37dc.js文件中?USE_HTML5_MODE的值為?true
進程外運行作業
默認情況下,所有作業都在當前的Web進程中運行。如果發現事件處理開始變慢的時候,可以啟動并擴展多個作業實例。通過在進程外運行作業,可以確保所有作業是否正常運行。
首先是要配置安裝Redis,這樣可以保證Exceptionless與作業之間能夠進行通信
更新?Web.config中的?RunJobsInProcess值為?false
更新作業的配置,有兩種方法可選:
使用環境變量進行配置Exceptionless。新增環境變量Exceptionless{SETTING NAME} (例如: ExceptionlessBaseURL, ExceptionlessElasticSearchConnectionString)。這是官方推薦的方法,因為它更簡單,而且當部署到azure時非常好用
打開AppData\jobs文件夾,然后按照在根目錄中?Web.config的配置,再重新配置每個作業的?xxx.exe.config。
在每個作業文件夾中都有一個?run.bat文件,雙擊它就會運行這個作業。當然,也可以將這些作業全部設置為Windows服務在后臺運行
更多設置
除了上面提到的設置,Exceptionless還支持很多自定義配置,下面是全部的設置列表,大家可根據自己的需要進行定制
列表按照這個格式進行排列:設置項 (數據類型,默認值)
更多日志類型
Exceptionless除了支持記錄Exception,也可以記錄LogMessage、Broken Links 、Feature Usages
LogMessage
LogMessage支持多種級別的日志信息
Other
Trace
Debug
Info
Warn
Error
Fatal
Off
用法也很簡單,直接在你想要記錄日志的地方直接加一句
ExceptionlessClient.Default.CreateLog("日志信息", LogLevel.Debug).AddTags("tag1", "tag2").Submit();所以我們在應用的過程中,可以添加一個統一的接口
public interface ILogger { void Debug(string message, params string[] tags); void Error(string message, params string[] tags); void Fatal(string message, params string[] tags); void Info(string message, params string[] tags); void Off(string message, params string[] tags); void Other(string message, params string[] tags); void Trace(string message, params string[] tags); void Warn(string message, params string[] tags); }using Exceptionless; using Exceptionless.Logging;public class ExceptionlessLogger : ILogger { public void Debug(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Debug).AddTags(tags).Submit(); } public void Error(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Error).AddTags(tags).Submit(); } public void Fatal(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Fatal).AddTags(tags).Submit(); } public void Info(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Info).AddTags(tags).Submit(); } public void Off(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Off).AddTags(tags).Submit(); } public void Other(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Other).AddTags(tags).Submit(); } public void Trace(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Trace).AddTags(tags).Submit(); } public void Warn(string message, params string[] tags) { ExceptionlessClient.Default.CreateLog(message, LogLevel.Warn).AddTags(tags).Submit(); } }然后在 Startup.cs的 ConfigureServices方法注入 ExceptionlessLogger
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<ILogger, ExceptionlessLogger>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }這樣就可以更方便地使用了
public class ValuesController : ControllerBase { public ILogger _logger; public ValuesController(ILogger logger) { _logger = logger; } // GET api/values/{id} [HttpGet("{id}")] public ActionResult<string> Get(int id) { try { _logger.Info("Test msg", "tag1", "tag2"); throw new Exception(); } catch (Exception ex) { ex.ToExceptionless().AddTags("tag1", "tag2").Submit(); } return $"value {id}"; } }Broken Links
記錄404找不到請求的日志
像我這里沒有添加favicon.ico圖標,使用Chrome瀏覽器會自動請求這個資源,因此,Exceptionless就記錄了這樣的日志
也可以直接在Api服務中調用如下面語句添加這種類型的日志
ExceptionlessClient.Default.CreateNotFound("404 not found").SetType("404").SetSource($"api/values/{id}");Feature Usages
類似的也可以添加Feature Usages日志
事件
上面所說的所有日志類型,最終都會通過事件進行記錄,Exceptionless也支持我們直接記錄一個事件
例子如下:
var dataDic = new Exceptionless.Models.DataDictionary(); dataDic.Add("key", "value"); ExceptionlessClient.Default.SubmitEvent(new Exceptionless.Models.Event { Count = 1, Date = DateTime.Now, Data = dataDic, Geo = "geo", Message = "message", ReferenceId = "referencelId", Source = "source", Tags = new Exceptionless.Models.TagSet() { "tags" }, Type = "type" });Exceptionless同時也支持我們捕獲事件提交過程和事件提交后的事件,這樣我們就可以在過程中做一些操作,例如可以忽略 404的請求,或者針對某些特殊日志返回某些信息
為了代碼的整潔,可以將Exceptionless的配置單獨放到一個cs文件中
添加一個 ExceptionlessBuilderExtensions類
public static class ExceptionlessBuilderExtensions { public static IApplicationBuilder UseExceptionless(this IApplicationBuilder app, IConfiguration configuration) { ExceptionlessClient.Default.Configuration.ApiKey = configuration["Exceptionless:ApiKey"]; ExceptionlessClient.Default.Configuration.ServerUrl = configuration["Exceptionless:ServerUrl"]; ExceptionlessClient.Default.SubmittingEvent += OnSubmittingEvent; app.UseExceptionless(); return app; } private static void OnSubmittingEvent(object sender, EventSubmittingEventArgs e) { if (e.Event.IsNotFound()) { e.Cancel = true;//取消事件提交 return; } // 修改日志信息 if (e.Event.Source == "sourceA") { e.Event.AddTags("systemLog"); } //TODO: } private static void OnSubmittedEvent(object sender, EventSubmittedEventArgs e) { // 做點什么東西 if (e.Event.Source == "sourceA") { //TODO: } } }然后修改 Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { …… app.UseExceptionless(Configuration); …… }Exceptionless 日志查詢
Exceptionless Web站點已經幫我們做好項目、時間、日志類型的分類,大家可以很直觀地進行操作查詢。
我這里要關注的是 Filter查詢
前面記錄日志的時候,有添加了 tag、 Type等信息,這時候就可以使用Filter進行查詢了。
語法:
or是用于查詢多個該類型值的日志時使用
例如:tag:tag1
列幾個可能比較常用的
source:"my log source" or "my log source"
type:error
level:Error
ip:127.0.0.1
如果是要同時輸入多種類型的條件:
[FilterType]:[value] {OR|AND} {[FilterType]:[value]}例如:tag:tag1 OR ip:127.0.0.1
更多的語法可以看官網說明
https://github.com/exceptionless/Exceptionless/wiki/Filtering-Searching
總結
在這篇文章中,我基本就是順著Exceptionless Self Hosting的介紹做了一遍,不過有一些東西因為沒有實際環境,所以也沒有去做,然后我這個也只是一個Demo,暫時也沒有做相關的壓力測試,所以也不知道這貨真正在生產環境大量用起來的時候會有一些什么表現,會不會踩到什么坑。歡迎大家在留言區跟我一起交流。今天就先跟大家介紹到這里,希望大家能持續關注我們。
參考文獻
本文在編寫過程中引用或參考了以下文章中的部分內容,如有侵權,請聯系修改或刪除。
https://www.cnblogs.com/edisonchou/p/exceptionlessdeploymentonproductionenv_introduction.html
https://www.cnblogs.com/ants/p/8580890.html
總結
以上是生活随笔為你收集整理的Exceptionless(二) - 使用进阶的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 函数式编程里的Materializati
- 下一篇: 基于 Kong 和 Kubernetes