-
Notifications
You must be signed in to change notification settings - Fork 135
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
Datadog Logs Module #1176
Datadog Logs Module #1176
Conversation
/// ... // customize using builder methods | ||
/// .build() | ||
/// | ||
public class Builder { |
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 is exact same builder as in v1.
internal let DatadogLogsFeatureName = "logging" | ||
|
||
internal struct DatadogLogsFeature: DatadogFeature { | ||
let name = DatadogLogsFeatureName |
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'm not happy with this, I think the name
should be a static requirement.
Datadog ReportBranch report: ✅ |
/// Creates `Directory` pointing to unique subfolder in `/var/folders/`. | ||
/// Does not create the subfolder - it must be later created with `.create()`. | ||
/// It returns different `Directory` each time it is called. | ||
public func obtainUniqueTemporaryDirectory() -> URL { |
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.
The temporary directory has been moved to TestUtilities
but without the dependency to Directory
or File
from the v1 module. By the end of the migration I'm hoping that this logic will be used by the IntegrationTests only.
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.
It may be also needed for large-scope tests in DatadogCore
- to test data storage and end-to-end interaction with mock V2 DatadogFeature
(it writes data → it uploads data). Also for small-scope tests like "file writer" or "files orchestrator".
/// Converts floating point value to fixed width integer with preventing overflow (and crash). | ||
/// In case of overflow, the value is converted to `.min` or `.max` respectively to its sign. | ||
/// - Parameter floatingPoint: the value to convert | ||
public init<T: BinaryFloatingPoint>(withNoOverflow floatingPoint: T) { |
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 is copied from SR 👍
let firstEventTime: UInt64 = try firstEvent.jsonMatcher.value(forKeyPath: "date") | ||
let secondEventTime: UInt64 = try secondEvent.jsonMatcher.value(forKeyPath: "date") | ||
let firstEventTime: Int64 = try firstEvent.jsonMatcher.value(forKeyPath: "date") | ||
let secondEventTime: Int64 = try secondEvent.jsonMatcher.value(forKeyPath: "date") |
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.
Dates in models are milliesec in Int64
.
public static var verbosityLevel: LogLevel? = nil | ||
public static var verbosityLevel: CoreLoggerLevel? = nil |
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.
Note that verbosity now uses levels from core and no longer from the Log Feature.
2489928
to
48f23c2
Compare
48f23c2
to
a16cf4a
Compare
c72c273
to
b1e24b6
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.
It looks good 👍. Due to the size of change I couldn't go deep into how we solved individual problems, but I asked some clarifying questions. Waiting for replies before approval 🙂.
import Foundation | ||
import DatadogInternal | ||
|
||
internal let DatadogLogsFeatureName = "logging" |
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.
nit/
internal let DatadogLogsFeatureName = "logging" | |
internal let datadogLogsFeatureName = "logging" |
or even
internal let DatadogLogsFeatureName = "logging" | |
internal let logsFeatureName = "logging" |
as it's internal. Maintaining "Datadog*" prefix for internal types could be tedious and misleading ("when to add it vs when not?"). Would be nice to have uniform convention.
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.
Yes, I'm also thinking of making the Feature name a static var in the DatadogFeature
protocol, so then we would do DatadogLogsFeature.name
, it would also simplify registration. In the meantime, I will commit your second suggestion 👍
/// | ||
/// // logger reference | ||
/// var logger = DatadogLogger.builder.build() | ||
public protocol Logger { |
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.
Keep in mind this is causing #250 - do we have a plan scheduled to tackle it during V2 migration? Seperate task might be enough to make sure we don't miss it.
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.
Yes, this Logger
won't be used as a type, only DatadogLogger
.
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.
Even then, the problem will be still there:
import DatadogLogs
let logger: Logger
☝️ It could be still ambiguous because Logger
could either mean DatadogLogs.Logger
protocol or Logger
struct/enum/protocol/class defined in app module. I think there is no other way around than changing the name if we want to keep it in public interface. DDLogger
could be a simple fix there - we could tackle it in separate JIRA task. WDYT?
@@ -24,14 +24,14 @@ public protocol LogEventMapper { | |||
/// Synchronous log event mapper. | |||
/// | |||
/// The class take a flat-map closure parameter for event scrubbing | |||
internal final class SyncLogEventMapper: LogEventMapper { | |||
public final class SyncLogEventMapper: LogEventMapper { |
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.
Why it needs to be public
now? In V1, the "sync" aspect of log mapper was internal 🤔💭.
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.
Indeed, I will check!
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.
So this class is used by the Datadog.Configuration.Builder
in the Datadog
module. It will be made internal when we split the config 👍
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.
Got it 👍, please track it in JIRA 👌.
@@ -27,5 +27,6 @@ Pod::Spec.new do |s| | |||
"Sources/_Datadog_Private/include/*.h"] | |||
|
|||
s.dependency 'DatadogInternal', s.version.to_s | |||
s.dependency 'DatadogLogs', s.version.to_s |
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.
Why do we need to add this dependency for DatadogCore
? If we keep adding all modules here, we won't achieve the V2 goal of selective dependency ("if I don't use DD Logs, I don't want to link it"), no?
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 is not the core yet, We need that dependency for initialisation. The configuration part will be tackled separately.
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.
Oh got it - it's transient and only for migration.
/// Creates `Directory` pointing to unique subfolder in `/var/folders/`. | ||
/// Does not create the subfolder - it must be later created with `.create()`. | ||
/// It returns different `Directory` each time it is called. | ||
public func obtainUniqueTemporaryDirectory() -> URL { |
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.
It may be also needed for large-scope tests in DatadogCore
- to test data storage and end-to-end interaction with mock V2 DatadogFeature
(it writes data → it uploads data). Also for small-scope tests like "file writer" or "files orchestrator".
Thanks for the review @ncreated and sorry again for this size. I've answered your comments, let me know if you need more clarification 👍 |
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.
Looks good 👍, thanks for answers 🙂.
What and why?
Create the
DatadogLogs
module.How?
DatatogInternal
utilsThe following definitions are now part of
DatadogInternal
Sampler
RelativeDateProvider
DDError
ProgrammerError
InternalError
SwiftExtensions.swift
DatadogLogger
The
DatadogLogger
is now the entry point of the Logs Feature.Configuration
The public initialise methods creates and register the Logs Feature to the given core:
This signature is not yet user-friendly and it will be revisited when we tackle configuration. Currently, only the
Datadog
module uses it.Builder
The
DatadogLogger
also exposes abuilder
static variable to configure and build a logger instance. This builder pattern stays untouch but will be revisited for a more idiomatic setup.Review checklist
Custom CI job configuration (optional)