11using System ;
22using System . Collections . Concurrent ;
3+ using System . Diagnostics ;
4+ using System . Net . Http ;
5+ using System . Net . Http . Headers ;
6+ using System . Security . Cryptography ;
7+ using System . Text ;
38using Microsoft . Extensions . Logging ;
49using Vtex . SplunkLogger ;
510
@@ -12,13 +17,51 @@ public static class ILoggerExtensions
1217 {
1318 static readonly EventId emptyEventId = new EventId ( ) ;
1419 static readonly ConcurrentDictionary < ILogger , MetricManager > metricManagers = new ConcurrentDictionary < ILogger , MetricManager > ( ) ;
20+ static readonly HttpClient evidenceHttpClient = CreateEvidenceHttpClient ( ) ;
21+
22+ static string Application = "" ;
23+
24+ static HttpClient CreateEvidenceHttpClient ( )
25+ {
26+ HttpClient httpClient = new HttpClient
27+ {
28+ BaseAddress = new Uri ( "http://evidence.vtex.com" ) , // This is a internal VTEX route. If you aren't from VTEX you will not be able to use it.
29+ MaxResponseContentBufferSize = 2147483647 ,
30+ Timeout = TimeSpan . FromSeconds ( 10 )
31+ } ;
32+ httpClient . DefaultRequestHeaders . Accept . Add ( new MediaTypeWithQualityHeaderValue ( "application/json" ) ) ;
33+ return httpClient ;
34+ }
1535
1636 static void KpiReady ( object sender , VTEXKpiEntry kpiEntry )
1737 {
1838 if ( sender is ILogger )
1939 ( ( ILogger ) sender ) . Log ( LogLevel . Critical , emptyEventId , kpiEntry , null , null ) ;
2040 }
2141
42+ static string GenerateHash ( string evidenceData )
43+ {
44+ var bytes = Encoding . UTF8 . GetBytes ( evidenceData ) ;
45+ byte [ ] md5Bytes = new byte [ ] { } ;
46+ using ( var md5Instance = MD5 . Create ( ) )
47+ {
48+ md5Bytes = md5Instance . ComputeHash ( bytes ) ;
49+ }
50+ return md5Bytes . ToHex ( ) ;
51+ }
52+
53+
54+ /// <summary>
55+ /// Method used to define application name at project startup.
56+ /// </summary>
57+ public static void SetApplication ( string application )
58+ {
59+ if ( string . IsNullOrWhiteSpace ( application ) )
60+ throw new ArgumentNullException ( nameof ( application ) ) ;
61+
62+ Application = application ;
63+ }
64+
2265 /// <summary>
2366 /// Log to Splunk.
2467 /// </summary>
@@ -31,10 +74,41 @@ static void KpiReady(object sender, VTEXKpiEntry kpiEntry)
3174 /// <param name="extraParameters">Extra parameters.</param>
3275 public static void DefineVTEXLog ( this ILogger logger , LogLevel logLevel , string workflowType , string workflowInstance , string account = "" , Exception exception = null , params Tuple < string , string > [ ] extraParameters )
3376 {
77+ if ( string . IsNullOrWhiteSpace ( Application ) )
78+ throw new NullReferenceException ( "You must call `ILoggerExtensions.SetApplication` method before call to save log." ) ;
79+
3480 string formattedMessage = string . Empty ;
81+ string evidenceHash = "" ;
82+ string evidenceText = "" ;
83+
84+ if ( exception != null )
85+ {
86+ evidenceText = string . Format (
87+ "Account: {1}{0}WorkflowType: {2}{0}WorkflowInstance: {3}{0}ExceptionType: {4}{0}ExceptionMessage: {5}{0}ExceptionBaseStack:{6}{0}ExceptionStack: {7}" ,
88+ Environment . NewLine ,
89+ account ,
90+ workflowType ,
91+ workflowInstance ,
92+ exception . GetType ( ) . Name ,
93+ exception . GetBaseException ( ) . Message ,
94+ exception . GetBaseException ( ) . StackTrace ,
95+ exception . StackTrace ) ;
96+ evidenceHash = GenerateHash ( evidenceText ) ;
97+ var putPath = $ "/api/evidence?application={ Application } &hash={ evidenceHash } ";
98+ evidenceHttpClient . PutAsync ( putPath , new StringContent ( evidenceText , Encoding . UTF8 , "text/plain" ) )
99+ . ContinueWith ( task => {
100+ if ( task . IsCompletedSuccessfully )
101+ Debug . WriteLine ( "VTEX Evidence Status: Sucess" ) ;
102+ else if ( task . IsCanceled )
103+ Debug . WriteLine ( "VTEX Evidence Status: Canceled" ) ;
104+ else
105+ Debug . WriteLine ( "VTEX Evidence Status: Error " + task . Exception != null ? task . Exception . ToString ( ) : "" ) ;
106+ } ) ; ;
107+ }
108+
35109 logger . Log ( logLevel ,
36110 emptyEventId ,
37- new VTEXLogEntry ( workflowType , workflowInstance , account , exception , extraParameters ) ,
111+ new VTEXLogEntry ( Application , workflowType , workflowInstance , account , evidenceHash , extraParameters ) ,
38112 exception , ( VTEXLogEntry arg1 , Exception arg2 ) =>
39113 {
40114 if ( string . IsNullOrWhiteSpace ( formattedMessage ) )
@@ -44,7 +118,8 @@ public static void DefineVTEXLog(this ILogger logger, LogLevel logLevel, string
44118 if ( exception != null )
45119 exceptionSegment = $ "Exception type: { exception . GetType ( ) . FullName } . Exception message: { exception . Message } ";
46120 var accountSegment = ! string . IsNullOrWhiteSpace ( account ) ? account : "-" ;
47- formattedMessage = string . Format ( $ "[{ logLevel } ] { eventSegment } { accountSegment } . { exceptionSegment } ") ;
121+ var evidenceSegment = ! string . IsNullOrWhiteSpace ( evidenceText ) ? $ "Evidence hash: { evidenceHash } . Evidence text: { evidenceText } " : "" ;
122+ formattedMessage = string . Format ( $ "[{ logLevel } ] { eventSegment } { accountSegment } .{ Environment . NewLine } { exceptionSegment } .{ Environment . NewLine } { evidenceSegment } ") ;
48123 }
49124 return formattedMessage ;
50125 } ) ;
@@ -60,7 +135,10 @@ public static void DefineVTEXLog(this ILogger logger, LogLevel logLevel, string
60135 /// <param name="extraParameters">Extra parameters.</param>
61136 public static void DefineVTEXKpi ( this ILogger logger , string kpiName , float kpiValue , string account = "" , params Tuple < string , string > [ ] extraParameters )
62137 {
63- metricManagers . GetOrAdd ( logger , new MetricManager ( logger , KpiReady ) ) . RegisterKpi ( kpiName , kpiValue , account , extraParameters ) ;
138+ if ( string . IsNullOrWhiteSpace ( Application ) )
139+ throw new NullReferenceException ( "You must call `ILoggerExtensions.SetApplication` method before call to save log." ) ;
140+
141+ metricManagers . GetOrAdd ( logger , new MetricManager ( logger , KpiReady ) ) . RegisterKpi ( Application , kpiName , kpiValue , account , extraParameters ) ;
64142 }
65143 }
66144}
0 commit comments