我正在尝试实现diagnostics
计算表达式以使用System.Diagnostics.DiagnosticSource
NuGet记录活动和事件。
但是我无法弄清楚我的计算表达式如何在两次调用自定义操作之间执行规则语句。
这是我目前的实现方式,并提供了我希望如何使用它的示例。
最后,它必须将整个表达式包装到try-finally
中,并使用最后一个上下文停止该活动。
open System.Diagnostics
[<Struct>]
type DiagnosticsState = {
Activity : Activity voption
Context : obj
}
with
member this.StartActivity (source : DiagnosticSource) activityName =
if ValueOption.isSome this.Activity
then invalidOp "Use yield to stop previous activity"
let activity =
if source.IsEnabled (activityName) then
let activity = Activity (activityName)
let eventName = activityName + ".Event"
if source.IsEnabled (eventName)
then source.StartActivity (activity, this.Context)
else activity.Start()
|> ValueSome
else ValueNone
let state = this
{ state with Activity = activity; Context = Unchecked.defaultof<_> }
member this.StopActivity (source : DiagnosticSource) =
match this.Activity with
| ValueSome activity ->
source.StopActivity (activity, this.Context)
| ValueNone -> ()
type DiagnosticsBuilder (sourceName) =
let source = new DiagnosticListener (sourceName) :> DiagnosticSource
//member __.Zero () =
// { Activity = ValueNone; Context = ValueNone }
member __.Yield (_) =
{ Activity = ValueNone; Context = ValueNone }
//member __.Combine (state1 : DiagnosticsState, state2 : DiagnosticsState) =
// state1.StopActivity source
// state2
//member __.Delay (f) = f()
member __.For (state, action : _ -> DiagnosticsState) =
action state
[<CustomOperation("activity")>]
member __.Activity (state : DiagnosticsState, activityName) =
state.StartActivity source activityName
[<CustomOperation("context")>]
member __.Context<'Context> (state : DiagnosticsState, context : 'Context) =
{ state with Context = context :> obj }
[<CustomOperation("event")>]
member __.Event (state : DiagnosticsState, eventName) =
if source.IsEnabled (eventName) then
source.Write(eventName, state.Context)
state
member __.Run (state : DiagnosticsState) = state.StopActivity source
let diagnostics = DiagnosticsBuilder "libid";;
diagnostics {
context "5"
printf "fdf"
activity "ace"
context 5
}