Skip to content

Commit

Permalink
Basic Logary logging in ASP.Net Core
Browse files Browse the repository at this point in the history
  • Loading branch information
haf committed Aug 29, 2019
1 parent b6feca4 commit bc3016b
Show file tree
Hide file tree
Showing 22 changed files with 445 additions and 319 deletions.
4 changes: 4 additions & 0 deletions examples/Logary.AspNetCore.API/Logary.AspNetCore.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@
<ProjectReference Include="..\..\src\targets\Logary.Targets.Jaeger\Logary.Targets.Jaeger.fsproj"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<Import Project="..\..\.paket\Paket.Restore.targets"/>
</Project>
5 changes: 4 additions & 1 deletion examples/Logary.AspNetCore.API/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Threading.Tasks;
using Logary.Configuration;
using Logary.Targets;
using Logary.Trace.Sampling;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
Expand All @@ -18,12 +19,13 @@ public static async Task Main(string[] args)
.LoggerMinLevel(".*", LogLevel.Verbose)
.Target<LiterateConsole.Builder>(
"literate",
lit => lit.Target.WithExtendedTokeniser().Done())
lit => lit.Target.WithSingleLineTokeniser().Done())
.Target<Logary.Targets.Jaeger.Builder>(
"jaeger",
x =>
x.Target
.WithJaegerAgent("localhost", 30831)
.WithSampler(new PerKeySampler(0.2, 100))
.Done())
);

Expand All @@ -33,6 +35,7 @@ public static async Task Main(string[] args)
static IWebHostBuilder CreateWebHostBuilder(string[] args, LogManager logary)
{
return WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services => services.AddLogary(logary))
.ConfigureLogging(logging => logging.AddLogary(logary))
.UseStartup<Startup>();
}
Expand Down
16 changes: 8 additions & 8 deletions examples/Logary.AspNetCore.API/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"Logary.AspNetCore.API": {
"commandName": "Project",
"launchBrowser": false,
"launchUrl": "api/todo",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Logary.AspNetCore.API": {
"commandName": "Project",
"launchBrowser": true,
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"launchUrl": "api/todo",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
"Microsoft": "Warning"
}
}
}
2 changes: 1 addition & 1 deletion examples/Logary.AspNetCore.API/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
"Default": "Debug"
}
},
"AllowedHosts": "*"
Expand Down
1 change: 1 addition & 0 deletions examples/Logary.Suave/Logary.Suave.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<Compile Include="AssemblyInfo.fs" />
<Compile Include="Program.fs" />
<None Include="paket.references" />
<ProjectReference Include="..\..\src\adapters\Logary.Adapters.Suave\Logary.Adapters.Suave.fsproj" />
<ProjectReference Include="..\..\src\Logary.Prometheus\Logary.Prometheus.fsproj" />
<ProjectReference Include="..\..\src\Logary\Logary.fsproj" />
<ProjectReference Include="..\..\src\adapters\Logary.Adapters.Facade\Logary.Adapters.Facade.fsproj" />
Expand Down
120 changes: 4 additions & 116 deletions examples/Logary.Suave/Program.fs
Original file line number Diff line number Diff line change
@@ -1,129 +1,17 @@
module Program

open Hopac
open Suave
open Suave.Successful
open Suave.Operators
open Suave.Filters
open Suave.RequestErrors
open Suave.Logging
open Suave.Successful
open Suave.Operators
open Hopac
open Logary
open Logary.Message
open Logary.Trace
open Logary.Trace.Propagation
open Logary.Targets
open Logary.Adapters.Facade
open Logary.Configuration
open Logary.Metric
open Logary.Targets

[<AutoOpen>]
module MoveMe =
open System
open System.Runtime.ExceptionServices

type Exception with
member x.reraise () =
ExceptionDispatchInfo.Capture(x).Throw()
Unchecked.defaultof<_>

module SuaveAdapter =

let getter: Getter<HttpContext> =
fun ctx nameOrPrefix ->
ctx.request.headers
|> List.filter (fun (name, _) -> name.StartsWith nameOrPrefix)
|> List.map (fun (name, value) -> name, value :: [])

let setter: Setter<HttpContext> =
fun (k: string, vs) ctx ->
if List.isEmpty vs then ctx else
let combinedHeaderValue = System.String.Join(",", vs)
let rec replaceFirstItem = function
| [], acc ->
// place at back
List.rev ((k, combinedHeaderValue) :: acc)
| (kC: string, _) :: tail, acc when kC.ToLowerInvariant() = k ->
// replace and return
List.rev ((kC, combinedHeaderValue) :: acc) @ tail
| _ :: tail, acc ->
// ignore, already replaced
replaceFirstItem (tail, acc)
{ ctx with response = { ctx.response with headers = replaceFirstItem (ctx.response.headers, []) } }

let UserStateLoggerKey = "Logary.Trace.SpanLogger"

type Logger with
member x.startSpan (ctx: HttpContext) =
let started = Global.timestamp()
let attrs, _, parentO = Jaeger.extract getter ctx
// https://github.com/open-telemetry/opentelemetry-specification/issues/210
// https://github.com/open-telemetry/opentelemetry-python/pull/89/files
let span =
x.buildSpan(sprintf "%O %s" ctx.request.method ctx.request.url.AbsolutePath, ?parent=parentO)
.setStarted(started)
.setKind(SpanKind.Server)
.setAttribute("component", "http")
.setAttribute("http.method", ctx.request.method.ToString())
.setAttribute("http.route", ctx.request.url.AbsolutePath)
.setAttribute("http.query", ctx.request.url.Query)
.setAttributes(attrs)
.start()

if ctx.request.queryFlag "debug" then span.debug()

let nextCtx = { ctx with userState = ctx.userState |> Map.add UserStateLoggerKey (box span) }

span, nextCtx

type SpanLogger with
member x.finish (res: HttpContext option) =
res |> Option.iter (fun ctx ->
if ctx.response.status.code >= 500 then
x.setStatus(SpanCanonicalCode.InternalError)
x.setAttribute("error", true)
elif ctx.response.status.code >= 400 then x.setAttribute("http.bad_request", true)
x.setAttribute("http.status_code", ctx.response.status.code)
x.setAttribute("http.status_text", ctx.response.status.reason)
)
x.finish ()

member x.finishWithExn (_: HttpContext, e: exn) =
x.setAttribute("http.status_code", 500)
x.setStatus(SpanCanonicalCode.InternalError, e.ToString())
x.setAttribute("error", true)
x.error (eventX "Unhandled error" >> addExn e)
x.finish()

type HttpContext with
member x.logger: SpanLogger =
match x.userState |> Map.tryFind UserStateLoggerKey with
| Some value ->
unbox value
| None ->
failwithf "Logary.Adapters.Suave Failed to find key '%s' in HttpContext.userState. Did you wrap your app using `withTracing`?" UserStateLoggerKey

let spanLogger (f: SpanLogger -> WebPart): WebPart =
context (fun ctx -> f ctx.logger)

let span (f: Span -> WebPart): WebPart =
context (fun ctx -> f ctx.logger)

let withTracing (logger: Logger) (app: WebPart) =
fun ctx ->
async {
let spanLogger, ctx = logger.startSpan ctx
spanLogger.logThrough()
try
let! res = app ctx
spanLogger.finish res
return res
with e ->
spanLogger.finishWithExn (ctx, e)
return e.reraise()
}

open Logary.Prometheus.Exporter
open SuaveAdapter

[<EntryPoint>]
let main _ =
Expand Down
12 changes: 8 additions & 4 deletions paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,12 @@ group MSFT
framework auto-detect
redirects on
nuget FSharp.Core ~> 4.7
nuget Microsoft.AspNetCore
nuget Microsoft.Extensions.Logging
nuget Microsoft.Extensions.DependencyInjection.Abstractions ~> 2.0
nuget Microsoft.Extensions.Hosting.Abstractions ~> 2.0
nuget Microsoft.Extensions.Logging ~> 2.0
nuget Microsoft.Extensions.Options ~> 2.0
nuget Microsoft.AspNetCore.Hosting.Abstractions ~> 2.0
nuget Microsoft.AspNetCore.Mvc.Core ~> 2.0

group Examples
source https://api.nuget.org/v3/index.json
Expand Down Expand Up @@ -123,5 +127,5 @@ group AspNetCoreExample
storage none
framework auto-detect
redirects on
nuget Microsoft.AspNetCore.App
nuget Microsoft.AspNetCore
nuget Microsoft.AspNetCore.App 2.2.5
nuget Microsoft.AspNetCore 2.2.0
Loading

0 comments on commit bc3016b

Please sign in to comment.