Skip to content

Commit db9a618

Browse files
authored
Process Log Format String for Logger Compatibility (#137)
* format string logger compatibility fix * refactor * discard unused argument * set access to private on added properties * use Interlocked.Increment for counter
1 parent dd53a1e commit db9a618

File tree

3 files changed

+48
-14
lines changed

3 files changed

+48
-14
lines changed

src/HttpHandler/Logging.fs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace Oryx
55

66
open System
77
open System.Text.RegularExpressions
8+
open System.Threading
89

910
open Microsoft.Extensions.Logging
1011
open FSharp.Control.TaskBuilder
@@ -15,6 +16,14 @@ module Logging =
1516
let private reqex =
1617
Regex(@"\{(.+?)(\[(.+?)\])?\}", RegexOptions.Multiline ||| RegexOptions.Compiled)
1718

19+
let private loggerFormatRegex =
20+
Regex($@"{{{PlaceHolder.ResponseHeader}\[(.+?)\]}}", RegexOptions.Multiline ||| RegexOptions.Compiled)
21+
22+
let mutable private placeholderCounter = 0
23+
24+
let private replacer (_: Match) : string =
25+
$"{{{PlaceHolder.ResponseHeader}__{Interlocked.Increment(&placeholderCounter)}}}"
26+
1827
let private getHeaderValue (headers: Map<string, seq<string>>) (key: string) : string =
1928
match headers.TryGetValue(key) with
2029
| (true, v) ->
@@ -57,7 +66,10 @@ module Logging =
5766
|> Array.ofSeq
5867

5968
let level, values = logLevel, getValues content
60-
logger.Log(level, format, values)
69+
70+
let formatCompatibilityString = loggerFormatRegex.Replace(format, replacer)
71+
72+
logger.Log(level, formatCompatibilityString, values)
6173
| _ -> ()
6274

6375
/// Set the logger (ILogger) to use. Usually you would use `HttpContext.withLogger` instead to set the logger for

test/Fetch.fs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ let ``Get with logging is OK`` () =
110110
// Arrange
111111
let metrics = TestMetrics()
112112
let logger = new TestLogger<string>()
113+
let msg = "custom message"
113114

114115
let stub =
115116
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>>(fun request token ->
@@ -124,18 +125,30 @@ let ``Get with logging is OK`` () =
124125

125126
let client = new HttpClient(new HttpMessageHandlerStub(stub))
126127

128+
let logPlaceholders =
129+
String.Join(
130+
"\n",
131+
[| "ResponseHeader[test]"
132+
"Message"
133+
"ResponseHeader[missing-key]"
134+
"ResponseHeader[X-Request-ID]"
135+
"ResponseHeader"
136+
"ResponseHeader["
137+
"ResponseHeader]"
138+
"ResponseHeader[[]]" |]
139+
|> Array.map (fun x -> $"{{{x}}}")
140+
)
141+
127142
let ctx =
128143
httpRequest
129144
|> withHttpClient client
130145
|> withUrlBuilder (fun _ -> "http://test.org/")
131146
|> withHeader ("api-key", "test-key")
147+
|> withLogMessage (msg)
132148
|> withMetrics metrics
133149
|> withLogger logger
134150
|> withLogLevel LogLevel.Debug
135-
|> withLogFormat (
136-
HttpContext.defaultLogFormat
137-
+ "\n← {ResponseHeader[test]}\n← {ResponseHeader[X-Request-ID]}\n← {ResponseHeader}"
138-
)
151+
|> withLogFormat (HttpContext.defaultLogFormat + $"\n← {logPlaceholders}\n← end")
139152
|> cache
140153

141154
// Act
@@ -150,8 +163,7 @@ let ``Get with logging is OK`` () =
150163
// Assert
151164
test <@ logger.Output.Contains "42" @>
152165
test <@ logger.Output.Contains "http://test.org" @>
153-
test <@ logger.Output.Contains "test-value" @>
154-
test <@ logger.Output.Contains "test-request-id" @>
166+
test <@ logger.Output.Contains $"test-value\n← {msg}\n\n← test-request-id\n\n\n\n\n← end" @>
155167
test <@ logger.Output.Contains "not-included-in-log" = false @>
156168
test <@ Result.isOk result @>
157169
test <@ metrics.Retries = 0L @>
@@ -185,17 +197,28 @@ let ``Post with logging is OK`` () =
185197
let content () =
186198
new StringableContent(json) :> HttpContent
187199

200+
let logPlaceholders =
201+
String.Join(
202+
"\n",
203+
[| "ResponseHeader[test]"
204+
"Message"
205+
"ResponseHeader[missing-key]"
206+
"ResponseHeader[X-Request-ID]"
207+
"ResponseHeader"
208+
"ResponseHeader["
209+
"ResponseHeader]"
210+
"ResponseHeader[[]]" |]
211+
|> Array.map (fun x -> $"{{{x}}}")
212+
)
213+
188214
let ctx =
189215
httpRequest
190216
|> withHttpClientFactory (fun () -> client)
191217
|> withUrlBuilder (fun _ -> "http://testing.org/")
192218
|> withHeader ("api-key", "test-key")
193219
|> withLogger (logger)
194220
|> withLogLevel LogLevel.Debug
195-
|> withLogFormat (
196-
HttpContext.defaultLogFormat
197-
+ "\n← {ResponseHeader[test]}\n← {ResponseHeader[X-Request-ID]}\n← {ResponseHeader}"
198-
)
221+
|> withLogFormat (HttpContext.defaultLogFormat + $"\n← {logPlaceholders}\n← end")
199222
|> cache
200223

201224
// Act
@@ -207,8 +230,7 @@ let ``Post with logging is OK`` () =
207230
test <@ logger.Output.Contains json @>
208231
test <@ logger.Output.Contains msg @>
209232
test <@ logger.Output.Contains "http://testing.org" @>
210-
test <@ logger.Output.Contains "test-value" @>
211-
test <@ logger.Output.Contains "test-request-id" @>
233+
test <@ logger.Output.Contains $"test-value\n← {msg}\n\n← test-request-id\n\n\n\n\n← end" @>
212234
test <@ logger.Output.Contains "not-included-in-log" = false @>
213235
test <@ Result.isOk result @>
214236
test <@ retries' = 1 @>

version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.4.1
1+
5.4.2

0 commit comments

Comments
 (0)