Created
October 23, 2015 03:26
-
-
Save neoeinstein/2d7e195f7d13e2c8b964 to your computer and use it in GitHub Desktop.
My in-progress attempt at creating a sink for serilog to logentries, which I halted after finding the JSON formatter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Logentries = | |
open System.IO | |
open System.Net.Sockets | |
open System.Net.Security | |
type Connection = | |
private | |
{ Client : TcpClient | |
Stream : Stream } | |
interface System.IDisposable with | |
member x.Dispose () = | |
try | |
x.Client.Close() | |
with | |
| e -> () | |
let [<Literal>] defaultHost = "api.logentries.com" | |
let [<Literal>] defaultPort = 10000 | |
let connectAsync (hubHost : string) (hubPort : int) = | |
async { | |
let client = new TcpClient() | |
client.NoDelay <- true | |
do! client.ConnectAsync(hubHost, hubPort) |> Async.AwaitTask | |
let stream = new SslStream(client.GetStream()) | |
stream.AuthenticateAsClient hubHost | |
return { Client = client; Stream = stream :> Stream } | |
} | |
let writeAsync conn buffer offset count = | |
conn.Stream.WriteAsync(buffer, offset, count) |> Async.AwaitTask | |
let flushAsync conn = | |
conn.Stream.FlushAsync() |> Async.AwaitTask | |
module Json = | |
open Serilog.Events | |
open Chiron | |
open Chiron.Operators | |
let ofLogEventLevel = | |
String << function | |
| LogEventLevel.Verbose -> "verbose" | |
| LogEventLevel.Debug -> "debug" | |
| LogEventLevel.Information -> "info" | |
| LogEventLevel.Warning -> "warn" | |
| LogEventLevel.Error -> "error" | |
| LogEventLevel.Fatal -> "fatal" | |
| _ -> "unknown" | |
let renderPropertyValue render = | |
use tw = new StringWriter() | |
render tw | |
tw.ToString | |
LogEventProperty("TEST", Serilog.Formatting.Json.JsonFormatter) | |
let ofLogEvent (x:LogEvent) = | |
Json.write "timestamp" x.Timestamp | |
*> Json.writeWith ofLogEventLevel "level" x.Level | |
*> Json.writeWithUnlessDefault (fun e -> String <| e.ToString()) "exception" null x.Exception | |
*> Json.write "template" x.MessageTemplate.Text | |
*> Json.write "properties" (x.Properties |> Seq.map (fun kvp -> kvp.Key, sprintf "%t" (renderPropertyValue kvp.Value.Render)) |> Map.ofSeq) | |
open Serilog.Sinks.PeriodicBatching | |
type LogentriesSink(?hubHost : string, ?hubPort : int, ?batchPostingLimit : int, ?batchPostingPeriod : System.TimeSpan) = | |
inherit PeriodicBatchingSink(defaultArg batchPostingLimit 50, defaultArg batchPostingPeriod (System.TimeSpan.FromSeconds(2.))) | |
let formatter = Serilog.Formatting.Display.MessageTemplateTextFormatter("{Timestamp:G} [{Level}] {Message}{NewLine}{Exception}", null) | |
override __.EmitBatch events = | |
if not <| Seq.isEmpty events then | |
async { | |
use! conn = connectAsync (defaultArg hubHost defaultHost) (defaultArg hubPort defaultPort) | |
events | |
|> Seq.iter | |
(fun e -> | |
use renderSpace = StringWriter() | |
) | |
} |> Async.RunSynchronously |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment