-
-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added LogProcessors and implemented shutdown and forceFlush for LoggerProviders #132
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finished self-review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ShutdownResult
and FlushResult
are use in both OpenTelemetry.Trace.Core
and OpenTelemetry.Logging.Core
so they are moved here.
-- | ||
-- ForceFlush SHOULD complete or abort within some timeout. ForceFlush can be implemented as a blocking API or an asynchronous API which notifies the caller via a callback or an event. OpenTelemetry SDK authors | ||
-- can decide if they want to make the flush timeout configurable. | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type is similar to Processor
defined in OpenTelemetry.Internal.Trace.Types
. Notable differences are the type variable body
because LogRecord
needs it, and changing onStart
and onEnd
to onEmit
in accordance with the spec. Maybe Processor
should be renamed to SpanProcessor
because there is more than one type of Processor now?
| -- | One or more exporters failed to successfully export one or more | ||
-- unexported spans. | ||
FlushError | ||
deriving (Show) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to Common
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mirrors Processor.hs
shutdownLoggerProvider LoggerProvider {loggerProviderProcessors} = liftIO $ do | ||
asyncShutdownResults <- V.forM loggerProviderProcessors $ \processor -> do | ||
logProcessorShutdown processor | ||
mapM_ wait asyncShutdownResults |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mirrors shutdownTracerProvider
jobs | ||
case mresult of | ||
Nothing -> pure FlushTimeout | ||
Just res -> pure res |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mirrors forceFlushTracerProvider
|
||
|
||
instance Show (TestLogProcessor body) where | ||
show _ = "LogProcessor {..}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added because shouldSatisfy
has a Show
constraint but (Show LogProcessor)
does not make sense because of the functions that are properties. "LogProcessor {..}"
is used to show that there are internal properties that exist but are not shown.
glp `shouldBe` lp | ||
fmap TestLogProcessor (loggerProviderProcessors glp) `shouldSatisfy` null | ||
loggerProviderResource glp `shouldBe` loggerProviderResource lp | ||
loggerProviderAttributeLimits glp `shouldBe` loggerProviderAttributeLimits lp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing each field separately is similar to testing the LoggerProvider
as a whole, but it makes more sense now that LogProcessor
s are part of LoggerProvider
.
, loggerProviderAttributeLimits :: AttributeLimits | ||
} | ||
deriving (Show, Eq) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cannot derive Show
and Eq
because Show
and Eq
instances do not make sense for LogProcessor
s because they contain functions.
9aeda12
to
62fd9ea
Compare
ea9dddb
to
079c965
Compare
import OpenTelemetry.Internal.Trace.Id (SpanId, TraceId) | ||
import OpenTelemetry.LogAttributes | ||
import OpenTelemetry.Resource (MaterializedResources) | ||
|
||
|
||
data LogProcessor body = LogProcessor | ||
{ logProcessorOnEmit :: IORef (ImmutableLogRecord body) -> Context -> IO () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly to the other PR, we should probably account for this naming style and provide a ReadWriteLogRecord here: https://opentelemetry.io/docs/specs/otel/logs/sdk/#additional-logrecord-interfaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that is a great idea, and I wrote a typeclass for ReadWriteLogRecord
but it is difficult to constrain this function because it is part of a record/datatype. Writing
logRecordProcessorOnEmit :: (ReadWriteLogRecord r) => r body -> Context -> IO ()
does not work because r
is not in scope. using GADTs, I could write
data LogRecordProcessor body where
LogRecordProcessor :: (ReadWriteLogRecord r)
=> { logRecordProcessorOnEmit :: r body -> Context -> IO ()
, ..
}
-> LogProcessor body
but creating a LogRecordProcessor
gives the error that r
is an ambiguous type variable because it could be any possible ReadWriteLogRecord
. I'm not sure of how to deal with this.
import OpenTelemetry.Internal.Trace.Id (SpanId, TraceId) | ||
import OpenTelemetry.LogAttributes | ||
import OpenTelemetry.Resource (MaterializedResources) | ||
|
||
|
||
data LogProcessor body = LogProcessor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be called LogRecordProcessor
: https://opentelemetry.io/docs/specs/otel/logs/sdk/#logrecordprocessor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. I named it LogProcessor
to be concise but I agree, it is more clear and correct if it is LogRecordProcessor
.
Approved pending the LogProcessor -> LogRecordProcessor rename |
4a91f00
to
c024ce3
Compare
079c965
to
2fb8bc4
Compare
c024ce3
to
be702b6
Compare
280ef90
to
8e6ce85
Compare
be702b6
to
7047eee
Compare
8e6ce85
to
dca8e47
Compare
7047eee
to
3c7470b
Compare
ca8248d
to
d4fc629
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finished self-review
|
||
-- | Logging is no-op when using this @LoggerProvider@ because it has no processors and empty options. | ||
noOpLoggerProvider = createLoggerProvider [] emptyLoggerProviderOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created to make it more clear when a LoggerProvider
is no-op. There are more possible no-op LoggerProvider
s than this, because, to my understanding, a LoggerProvider
is no-op when its processors are no-op.
import OpenTelemetry.Internal.Trace.Id (SpanId, TraceId) | ||
import OpenTelemetry.LogAttributes | ||
import OpenTelemetry.Resource (MaterializedResources) | ||
|
||
|
||
data LogProcessor body = LogProcessor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. I named it LogProcessor
to be concise but I agree, it is more clear and correct if it is LogRecordProcessor
.
2dd6a5b
to
36ca23f
Compare
36ca23f
to
ec5674e
Compare
02348f1
to
fd39cc4
Compare
cb620e4
to
db00438
Compare
8503d1f
to
76b7962
Compare
db00438
to
44fc9d0
Compare
76b7962
to
2b3cf49
Compare
516d129
to
f0efc2d
Compare
b6a4c70
to
5af2e9e
Compare
f0efc2d
to
b3752a2
Compare
b3752a2
to
bc48af2
Compare
Big Context
Logging Support is being added to hs-opentelemetry. Logging spec
Small (This PR) Context
LogProcessor
s are a sort of middleman betweenLogRecord
s andLogExporter
s that allow for modification ofLogRecord
s after creation. This PR creates aLogProcessor
type that containsonEmit
,shutdown
, andforceFlush
methods. It also createsshutdown
andforceFlush
functions forLoggerProvider
s that call theshutdown
andforceFlush
methods of internalLogProcessor
s.Testing
stack build
runsLoggerProvider
type, but no new test written forLogProcessor
s. It would probable make more sense to write individual tests for each implementedLogProcessor