1
1
using System ;
2
2
using 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 ;
3
8
using Microsoft . Extensions . Logging ;
4
9
using Vtex . SplunkLogger ;
5
10
@@ -12,13 +17,51 @@ public static class ILoggerExtensions
12
17
{
13
18
static readonly EventId emptyEventId = new EventId ( ) ;
14
19
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
+ }
15
35
16
36
static void KpiReady ( object sender , VTEXKpiEntry kpiEntry )
17
37
{
18
38
if ( sender is ILogger )
19
39
( ( ILogger ) sender ) . Log ( LogLevel . Critical , emptyEventId , kpiEntry , null , null ) ;
20
40
}
21
41
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
+
22
65
/// <summary>
23
66
/// Log to Splunk.
24
67
/// </summary>
@@ -31,10 +74,41 @@ static void KpiReady(object sender, VTEXKpiEntry kpiEntry)
31
74
/// <param name="extraParameters">Extra parameters.</param>
32
75
public static void DefineVTEXLog ( this ILogger logger , LogLevel logLevel , string workflowType , string workflowInstance , string account = "" , Exception exception = null , params Tuple < string , string > [ ] extraParameters )
33
76
{
77
+ if ( string . IsNullOrWhiteSpace ( Application ) )
78
+ throw new NullReferenceException ( "You must call `ILoggerExtensions.SetApplication` method before call to save log." ) ;
79
+
34
80
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
+
35
109
logger . Log ( logLevel ,
36
110
emptyEventId ,
37
- new VTEXLogEntry ( workflowType , workflowInstance , account , exception , extraParameters ) ,
111
+ new VTEXLogEntry ( Application , workflowType , workflowInstance , account , evidenceHash , extraParameters ) ,
38
112
exception , ( VTEXLogEntry arg1 , Exception arg2 ) =>
39
113
{
40
114
if ( string . IsNullOrWhiteSpace ( formattedMessage ) )
@@ -44,7 +118,8 @@ public static void DefineVTEXLog(this ILogger logger, LogLevel logLevel, string
44
118
if ( exception != null )
45
119
exceptionSegment = $ "Exception type: { exception . GetType ( ) . FullName } . Exception message: { exception . Message } ";
46
120
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 } ") ;
48
123
}
49
124
return formattedMessage ;
50
125
} ) ;
@@ -60,7 +135,10 @@ public static void DefineVTEXLog(this ILogger logger, LogLevel logLevel, string
60
135
/// <param name="extraParameters">Extra parameters.</param>
61
136
public static void DefineVTEXKpi ( this ILogger logger , string kpiName , float kpiValue , string account = "" , params Tuple < string , string > [ ] extraParameters )
62
137
{
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 ) ;
64
142
}
65
143
}
66
144
}
0 commit comments