エラー通知:各回路から独自の方法で

概念的に



簡単な目標



すべてのアプリケーションインスタンスのエラーについて、責任者に迅速に(瞬時に)通知する必要があります。 さらに、さまざまなインスタンスに対して、ログ配信のさまざまな方法が必要です。プログラマによるローカル起動の場合は、彼にのみ通知します。 PRODAから-プロジェクトのリーダー、すぐに彼らを動員します。 テストサーバーから-対応する回路を担当します。







詳細に



NLogを使用すると、アプリケーションコード(C#コードには_logger.Info(メッセージ)または_logger.Error(例外)があります )ではなく、xml構成ファイルNLog.configにログを配信する方法を構成できます。 さまざまなレベル(およびその他の必要な条件)のこのファイルのレベルで、さまざまな配信方法を設定できます。 4つの主な方法があります。









プラグインを使用してアプリケーションにアタッチすることで独自の方法を作成できるなど、他の方法もあります。







Webアプリケーションでエラー(例外)を迅速に配信するには、それらを電子メールで配信するのが最善です。 他のすべての(情報)ログは、 データベースまたはファイルに保存できます 。 また、コンソールアプリケーションを起動する場合、すべてがコンソールにあります。 したがって、同じC#コード(C#ライブラリ)を実行する場合、ログは異なる方法で配信する必要があります-これは、起動したアプリケーションのプロジェクトに保存されている別のファイルNLog.configで配信条件を強調表示することで実現します。







同じログ記録を複数の方法で同時に配信できます。たとえば、電子メールによる送信以外のエラーはメインログストレージに保存する必要があります。







異なるループ(アプリケーションインスタンス)のログ配信に異なる設定を行うには、構成変換を使用する必要があります。 そうする必要があり、彼らの助けを借りて、次のことが可能です:









このため、C#ソースを編集する必要はありません-実行中の異なるプロジェクトに異なるNLog.configファイルがあり、これらのファイルに構成変換が あれば十分です。







方法



これはすべて、config-fileのログ設定を削除して(NLogを提供します)、 設定変換を設定することで可能になります。







Nlog.config



ターゲットを定義しました:







databaseLog
<target name="databaseLog" dbProvider="mssql" xsi:type="Database" connectionString="Data Source=${sqlserver}; Initial Catalog=Logs;Persist Security Info=True;User ID=log_writer;Password=gfhjkm;Application Name=${src} Logger;" commandText="exec AddLog @MachineName=@machinename, @Source=@source, @SubSource=@subsource, @Level=@level, @ThreadName=@threadname, @ThreadId=@threadid, @ProcessName=@pn, @ProcessFullName=@pfn, @Msg=@message" > <parameter name="@machinename" layout="${machinename}" /> <parameter name="@source" layout="${src}" /> <parameter name="@subsource" layout="${logger}" /> <parameter name="@level" layout="${level}" /> <parameter name="@threadname" layout="${threadname}" /> <parameter name="@threadid" layout="${threadid}" /> <parameter name="@pn" layout="${processname:fullName=false}" /> <parameter name="@pfn" layout="${processname:fullName=true}" /> <parameter name="@message" layout="${message}. ${exception:format=ToString}" /> </target>
      
      





mailtargetError
 <target name="mailtargetError" xsi:type="Mail" html="false" addNewLines="true" encoding="UTF-8" subject="${src} error notification (server ${machinename}, iis ${iis-site-name})" header="Runtime error in project ${src} at server ${machinename}, iis site ${iis-site-name}. ${newline} ${newline} " body="${date:format=dd.MM.yyyy HH\:mm\:ss} Thread=${threadname}:${threadid} ${level:uppercase=true} in ${logger}: ${newline} ${newline} ${message}. ${exception:format=ToString} ${newline} ${newline} Process [${processname:fullName=true}] ${newline} (${processname:fullName=false})" to="${mails_error_reciever}" from="${mails_error_sender}" smtpAuthentication="None" smtpServer="${mails_error_smtpserver}" smtpPort="25" />
      
      





コンソール
 <target xsi:type="Console" name="Console" layout="Thread ${threadname}:${threadid} ${level:uppercase=true} ${logger}: ${message}. ${exception:format=ToString}" error="true" />
      
      





WebアプリケーションのNLog.configルール次のようになります。







 <rules> <logger name="*" minlevel="Trace" writeTo="databaseLog" /> <logger name="*" minlevel="Error" writeTo="mailtargetError"/> </rules>
      
      





このようなレコードは、エラーが電子メールで送信されてデータベースに書き込まれ、レベル以下のすべてのログがデータベースにのみ書き込まれることを意味します。







コンソールの配信ルールは次のようになります。







 <rules> <logger name="*" minlevel="Trace" writeTo="Console" /> </rules>
      
      





すべてのログをコンソールに出力することを意味します。







構成変換のパラメーターを個別に再定義できるように、nlog変数を出力できます。







 <variable name="fileLogDir" value="${basedir}/log"/> <variable name="fileLayout" value="${date:format=dd.MM.yyyy HH\:mm\:ss} Thread=${threadname}:${threadid} ${level:uppercase=true} in ${logger}: ${message}. ${exception:format=ToString}"/> <variable name="sqlserver" value="sqlserver_logs"/> <variable name="mails_error_smtpserver" value="mail.company.com"/> <variable name="mails_error_reciever" value="konstantin.chernyaev@company.com"/> <variable name="mails_error_sender" value="project@company.com"/>
      
      





追加データを記録する



NLogでは、この情報行またはexception'aに加えて、非常に多くのデータを表示できます( ドキュメントを参照)。 特別なデータを保存する必要がある場合、これはevent-propertiesを使用して可能です:







 LogEventInfo e = new LogEventInfo(LogLevel.Info, _logger.Name, "message"); e.Properties["userId"] = user.Id; _logger.Log(e);
      
      





次に、 NLog.configで変数$ {event-properties:item = domainId}を使用できます。







 <target name="databaseLogCustom" dbProvider="mssql" xsi:type="Database" commandText="exec AddLog @UserId = @userid, ..." ... > <parameter name="@userid" layout="${event-properties:item=domainId}" /> ...
      
      





構成変換



1) 構成変換は、 ソリューション構成でのみ可能です。 したがって、各回路(アプリケーションのインスタンス)ごとに、開発者ごとに-独自のものが必要です。 個人用ソリューション構成の例:











2)アクティブとして選択します:







3)次に、Visual Studio拡張機能「 構成変換 」( https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform )をインストールする必要があります

インストール後、 任意のファイルについて (!)ソリューションエクスプローラーに、「 構成変換の追加 」、「 構成変換のプレビュー 」の項目が表示されます。











4)「 Add Config Transforms 」という項目は、このファイルの各プロジェクト構成(ソリューションではありません!)に「 name.configuration name.extension 」という形式のファイルを追加することを意味します。



これにより、プロジェクトファイル(.csproj)に必要なタグが追加されます。

例はApp.configNLog.configです:







 <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="App_config_AfterCompile" AfterTargets="AfterCompile" Condition="Exists('App.$(Configuration).config')"> <!--Generate transformed app config in the intermediate directory--> <TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" /> <!--Force build process to use the transformed configuration file from now on.--> <ItemGroup> <AppConfigWithTargetPath Remove="App.config" /> <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config"> <TargetPath>$(TargetFileName).config</TargetPath> </AppConfigWithTargetPath> </ItemGroup> </Target> <!--Override After Publish to support ClickOnce AfterPublish. Target replaces the untransformed config file copied to the deployment directory with the transformed one.--> <Target Name="App_config_AfterPublish" AfterTargets="AfterPublish" Condition="Exists('App.$(Configuration).config')"> <PropertyGroup> <DeployedConfig>$(_DeploymentApplicationDir)$(TargetName)$(TargetExt).config$(_DeploymentFileMappingExtension)</DeployedConfig> </PropertyGroup> <!--Publish copies the untransformed App.config to deployment directory so overwrite it--> <Copy Condition="Exists('$(DeployedConfig)')" SourceFiles="$(IntermediateOutputPath)$(TargetFileName).config" DestinationFiles="$(DeployedConfig)" /> </Target> <Target Name="NLog_config_AfterBuild" AfterTargets="AfterBuild" Condition="Exists('NLog.$(Configuration).config')"> <TransformXml Source="NLog.config" Destination="$(OutputPath)NLog.config" Transform="NLog.$(Configuration).config" /> </Target>
      
      





(TeamCityはビルドプロセスの一部であるため、これらの変換を選択します)







タグのこのスペルを使用すると、ソースファイルWeb.configNLog.configは変更されず、結果のファイルのみが編集され、アセンブリフォルダーに配置されます-これは、開発者が個人的なソリューション構成を持っている場合、常に変更およびコミットされないことを意味しますこのファイルにはさまざまな変換があります。







5次に、パーソナルソリューション構成に対応する作成されたNLog.username.configファイルで、エラー受信者のアドレスを置き換える必要があります。







 <variable name="mails_error_reciever" value="konstantin.chernyaev@company.com" xdt:Locator="Match(name)" xdt:Transform="SetAttributes"/>
      
      





そして、生産回路の場合(例えば):







 <variable name="mails_error_reciever" value="developers@company.com" xdt:Locator="Match(name)" xdt:Transform="SetAttributes"/>
      
      





変換の作成に関するヘルプ



変換の記述に関する包括的なヘルプ: https : //msdn.microsoft.com/en-us/library/dd465326(v=vs.110).aspx







簡単に:

タグ全体を置き換えるには、 xdt:Transform = "Replace"属性でマークする必要があります。







 <rules xdt:Transform="Replace"> <logger name="*" minlevel="Trace" writeTo="databaseLog" /> <logger name="*" minlevel="Error" writeTo="mailtargetError"/> </rules>
      
      





タグ全体を削除するには、 xdtでマークする必要があります:Transform = "Remove"属性:







 <authorization> <deny xdt:Transform="Remove" /> </authorization>
      
      





タグを挿入するには、属性xdtでマークする必要があります:Transform = "Insert"







 <nlog> <targets> <target ... xdt:Transform="Insert" >
      
      





タグの属性を追加するには、属性xdt:Transform = "SetAttributes(sptを介した属性のリスト)"でマークし、属性自体を追加する必要があります。







 <compilation debug="true" xdt:Transform="SetAttributes(debug)" />
      
      





タグの属性を削除するには、属性xdtでマークする必要があります。Transform = "RemoveAttributes(RFP経由の属性のリスト)"







 <compilation xdt:Transform="RemoveAttributes(debug)" />
      
      





属性値を置き換えるには、属性xdt:Locator = "Match(name)" xdt:Transform = "SetAttributes"にタグを付ける必要があります。







 <connectionStrings> <add name="CS" connectionString="Data Source=dbserver;Initial Catalog=DB;Persist Security Info=True;User ID=usr;Password=psw" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
      
      





結果



開発者がVisual StudioからWebプロジェクトを開始すると、エラーメッセージは、 NLog.Prodに示されているように、コンソールから(コンソールでPRODで起動されたときに)コンソールから起動されたときに、起動中の開発者(上記のすべてを行う場合)にのみ送信されます.config









Global.asax.cs







 static readonly Logger _logger = LogManager.GetLogger("Global.asax"); protected void Application_Error(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; Exception ex = Server.GetLastError(); _logger.Fatal(ex, $"Application_Error: {app.Context.Request.RawUrl}"); }
      
      





WebAPIコントローラー:







 //  : static readonly Logger _logger = LogManager.GetLogger("( )"); //  : try { // code } catch (SomeSoftException ex) { return BadRequest(ex.Message); } catch (Exception ex) { _logger.Error(ex); //  email     return base.InternalServerError(ex); }
      
      






All Articles