From 31dc39d60e34ddecfffd6bc30c2a74f5ec9e069e Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Thu, 11 Oct 2018 18:44:43 +0100 Subject: [PATCH 1/3] Pad build numbers and prefix PRs This will create stuff like: `MyLib.0.1.0-CI0000798.nupkg` (from master) `MyLib.0.1.0-pr17-0000798.nupkg` (from PRs) --- build.cmd | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build.cmd b/build.cmd index 806e875..c3cff58 100644 --- a/build.cmd +++ b/build.cmd @@ -1,8 +1,16 @@ -dotnet pack src/CallPolly --configuration Release -o "%CD%\bin" --version-suffix CI%1 +SETLOCAL +SET X=%1 +SET BLD=000000%X% +SET BLD=%BLD:~-7% +if [%2]==[] (SET V=CI%BLD%) else (SET V=pr%2-%BLD%) + +dotnet pack src/CallPolly --configuration Release -o "%CD%\bin" --version-suffix %V% if ERRORLEVEL 1 (echo Error building CallPolly; exit /b 1) dotnet test tests/CallPolly.Tests --configuration Release if ERRORLEVEL 1 (echo Error testing CallPolly; exit /b 1) dotnet test tests/CallPolly.Acceptance --configuration Release -if ERRORLEVEL 1 (echo Error acceptance testing CallPolly; exit /b 1) \ No newline at end of file +if ERRORLEVEL 1 (echo Error acceptance testing CallPolly; exit /b 1) + +ENDLOCAL From c8f18726567be2addc5eb9875fb2c6050e2c3611 Mon Sep 17 00:00:00 2001 From: Ruben Bartelink Date: Sun, 14 Oct 2018 17:19:01 +0100 Subject: [PATCH 2/3] Polish change logging, fix change detection --- src/CallPolly/Context.fs | 41 +++++++++++++++++++++++----------------- src/CallPolly/Parser.fs | 4 ++-- src/CallPolly/Rules.fs | 10 +++++----- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/CallPolly/Context.fs b/src/CallPolly/Context.fs index 7ddbf4f..4c474a9 100644 --- a/src/CallPolly/Context.fs +++ b/src/CallPolly/Context.fs @@ -3,6 +3,17 @@ open Serilog open System +module private SerilogHelpers = + let inline kv x y = System.Collections.Generic.KeyValuePair<_,_>(x,y) + let inline lo x (*lp*) = Serilog.Events.StructureValue x + let inline ls x (*lp seq*)= Serilog.Events.SequenceValue x + let inline ld x (*lv,kvp(lv)*) = Serilog.Events.DictionaryValue x + let inline lp n v(*:lo/lv/ls/ld*) = Serilog.Events.LogEventProperty(n, v) + let inline lv (x:#obj) = Serilog.Events.ScalarValue(x) + let forContextExplicit k v (log : ILogger) = + let enrich (e : Serilog.Events.LogEvent) = e.AddPropertyIfAbsent(Serilog.Events.LogEventProperty(k, v)) + log.ForContext({ new Serilog.Core.ILogEventEnricher with member __.Enrich(evt,_) = enrich evt }) + module private Impl = type Warning = { service: string; call: string; ruleText: string } @@ -11,9 +22,9 @@ module private Impl = let mutable current = readDefinitions () let ingest () = let res = Parser.parse current - if not (List.isEmpty res.Warnings) then - let msgs = seq { for w in res.Warnings -> { service=w.serviceName; call=w.callName; ruleText = string w.unknownRule } } - log.ForContext("{count} Warnings", msgs, true).Warning("Definition had {count} unrecognized rules", List.length res.Warnings) + if not (Array.isEmpty res.Warnings) then + let msgs = seq { for w in res.Warnings -> { service=w.serviceName; call=w.callName; ruleText=string w.unknownRule } } + log.ForContext("warnings", msgs).Warning("Policy definitions had {count} unrecognized rules", res.Warnings.Length) res let tryReadUpdates () = let updated = readDefinitions() @@ -24,20 +35,16 @@ module private Impl = ingest(),tryReadUpdates - type ServicePolicyUpdate = - { service: string - actionUpdates: (string * CallPolly.Rules.ChangeLevel) [] } - - let logChanges (log: ILogger) res = - let changes = - seq { for service, actionUpdates in res -> { service = service; actionUpdates = List.toArray actionUpdates } } - |> Seq.distinct - |> Seq.cache - log - .ForContext("dump", changes, true) - .Information("Updated {count} values for {@services}", - Seq.length changes, - seq { for x in changes -> x.service, Array.length x.actionUpdates }); + open SerilogHelpers + let logChanges (log: ILogger) (res: (string*(string*Rules.ChangeLevel) list) list) = + let xs = res |> Seq.filter (function _,c -> not (List.isEmpty c)) |> Seq.sortBy (function _,c -> -List.length c) |> Seq.cache + if not (Seq.isEmpty xs) then + //.ForContext("changes", seq { for s,calls in xs do for c,change in calls -> sprintf "%s:%s:%O" s c change }, true ) + let changesAsDictionary calls = ld (seq { for callname,change in calls -> kv (lv callname) (lv (string change) :> _) }) + let dump = ls <| seq { for s,calls in xs -> lo [ lp "service" (lv s); lp "changes" (changesAsDictionary calls)] } + (log |> forContextExplicit "dump" dump).Information("Updated {count} values for {services}", + xs |> Seq.sumBy (function _service,changes -> changes.Length), + xs |> Seq.map (function service,changes -> kv service changes.Length)) [] type CallPolicyInternalState = diff --git a/src/CallPolly/Parser.fs b/src/CallPolly/Parser.fs index 4155247..57e6fd1 100644 --- a/src/CallPolly/Parser.fs +++ b/src/CallPolly/Parser.fs @@ -173,13 +173,13 @@ type ParseResult(services: ParsedService[]) = let mapped = services |> Seq.map mapService member __.Warnings = - [ for service in services do + [| for service in services do for call in service.calls do for rule in call.rules do match rule with | ParsedRule.Unknown jo -> yield { serviceName = service.serviceName; callName = call.callName; unknownRule = jo } - | _ -> () ] + | _ -> () |] member __.Raw : Map> = Map.ofSeq <| seq { for service in services -> diff --git a/src/CallPolly/Rules.fs b/src/CallPolly/Rules.fs index 7d92dc4..2b091d0 100644 --- a/src/CallPolly/Rules.fs +++ b/src/CallPolly/Rules.fs @@ -189,14 +189,14 @@ type CallPolicy<'TConfig when 'TConfig: equality> (makeGoverner : CallConfig<'TC /// Ingest an updated set of config values, reporting diffs, if any member __.TryUpdate(updated : CallConfig<'TConfig>) = - let changes = + let level = match updated.policy = cfg.policy, updated.config = cfg.config with - | true, true -> Some ChangeLevel.ConfigurationAndPolicy + | false, false -> Some ChangeLevel.ConfigurationAndPolicy | true, false -> Some ChangeLevel.Configuration | false, true -> Some ChangeLevel.Policy - | false, false -> None + | true, true -> None - match changes with + match level with | Some ChangeLevel.ConfigurationAndPolicy | Some ChangeLevel.Policy -> governor <- makeGoverner updated cfg <- updated @@ -204,7 +204,7 @@ type CallPolicy<'TConfig when 'TConfig: equality> (makeGoverner : CallConfig<'TC cfg <- updated | _ -> () - changes + level member __.Policy = cfg.policy member __.Config = cfg.config From 9f5b1ac8a279ed8441778520616b685182687ef5 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Sun, 14 Oct 2018 20:25:24 +0100 Subject: [PATCH 3/3] Add link in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 59af085..b270210 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ CallPolly wraps Polly to provide: ## Non-goals -- low level policy implementations should live elsewhere (see _CONTRIBUTION notes_) +- low level policy implementations should live elsewhere (see [CONTRIBUTION notes](#contribution-notes)) - the core CallPolly library faciltates, but should never bind _directly_ to any specific log or metrics emission sink # Dependencies @@ -102,4 +102,4 @@ See the [acceptance tests](https://github.com/jet/CallPolly/blob/master/tests/Ca } } -``` \ No newline at end of file +```