Skip to content

Instantly share code, notes, and snippets.

@neoeinstein
Created October 23, 2015 03:26
Show Gist options
  • Save neoeinstein/2d7e195f7d13e2c8b964 to your computer and use it in GitHub Desktop.
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.
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