Skip to content

Commit

Permalink
Merge pull request #130 from DataDog/ncreated/RUMM-494-add-millisecon…
Browse files Browse the repository at this point in the history
…ds-precision-on-ios-11.1

RUMM-494 Add milliseconds precision on iOS 11.0 and 11.1
  • Loading branch information
ncreated authored Jun 10, 2020
2 parents 48fde30 + 9da414b commit 1e84928
Show file tree
Hide file tree
Showing 17 changed files with 262 additions and 169 deletions.
30 changes: 22 additions & 8 deletions Datadog/Datadog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,22 @@
612983CD2449E62E00D4424B /* LoggingFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612983CC2449E62E00D4424B /* LoggingFeature.swift */; };
61345613244756E300E7DA6B /* PerformancePresetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61345612244756E300E7DA6B /* PerformancePresetTests.swift */; };
614E9EB3244719FA007EE3E1 /* BundleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614E9EB2244719FA007EE3E1 /* BundleType.swift */; };
618C365F248E85B400520CDE /* DateFormattingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618C365E248E85B400520CDE /* DateFormattingTests.swift */; };
61B558CF2469561C001460D3 /* LoggerBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B558CE2469561C001460D3 /* LoggerBuilderTests.swift */; };
61BB2B1B244A185D009F3F56 /* PerformancePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61BB2B1A244A185D009F3F56 /* PerformancePreset.swift */; };
61C363802436164B00C4D4E6 /* ObjcExceptionHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3637F2436164B00C4D4E6 /* ObjcExceptionHandlerTests.swift */; };
61C3638324361BE200C4D4E6 /* DatadogPrivateMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3638224361BE200C4D4E6 /* DatadogPrivateMocks.swift */; };
61C3638524361E9200C4D4E6 /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3638424361E9200C4D4E6 /* Globals.swift */; };
61C36470243B5C8300C4D4E6 /* ServerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3646F243B5C8300C4D4E6 /* ServerMock.swift */; };
61D45807248A667600A7F284 /* DateFormatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8DE24615B89008E5063 /* DateFormatting.swift */; };
61F8CC092469295500FE2908 /* DatadogConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F8CC082469295500FE2908 /* DatadogConfigurationTests.swift */; };
61FB222D244A21ED00902D19 /* LoggingFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FB222C244A21ED00902D19 /* LoggingFeatureMocks.swift */; };
61FB2230244E1BE900902D19 /* LoggingFeatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FB222F244E1BE900902D19 /* LoggingFeatureTests.swift */; };
9E2FB2722447660E001C9B7B /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61133B82242393DE00786299 /* Datadog.framework */; };
9E36D92224373EA700BFBDB7 /* SwiftExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E36D92124373EA700BFBDB7 /* SwiftExtensionsTests.swift */; };
9E58E8DF24615B89008E5063 /* ISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8DE24615B89008E5063 /* ISO8601DateFormatter.swift */; };
9E58E8DF24615B89008E5063 /* DateFormatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8DE24615B89008E5063 /* DateFormatting.swift */; };
9E58E8E124615C75008E5063 /* JSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8E024615C75008E5063 /* JSONEncoder.swift */; };
9E58E8E324615EDA008E5063 /* EncodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8E224615EDA008E5063 /* EncodingTests.swift */; };
9E58E8E324615EDA008E5063 /* JSONEncoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8E224615EDA008E5063 /* JSONEncoderTests.swift */; };
9E68FB55244707FD0013A8AA /* ObjcExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E68FB53244707FD0013A8AA /* ObjcExceptionHandler.m */; };
9E68FB56244707FD0013A8AA /* ObjcExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E68FB54244707FD0013A8AA /* ObjcExceptionHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
9EA6A539244897A900621535 /* LoggingIOBenchmarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA6A538244897A900621535 /* LoggingIOBenchmarkTests.swift */; };
Expand Down Expand Up @@ -240,6 +242,7 @@
612983CC2449E62E00D4424B /* LoggingFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingFeature.swift; sourceTree = "<group>"; };
61345612244756E300E7DA6B /* PerformancePresetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformancePresetTests.swift; sourceTree = "<group>"; };
614E9EB2244719FA007EE3E1 /* BundleType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleType.swift; sourceTree = "<group>"; };
618C365E248E85B400520CDE /* DateFormattingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateFormattingTests.swift; sourceTree = "<group>"; };
61B558CE2469561C001460D3 /* LoggerBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerBuilderTests.swift; sourceTree = "<group>"; };
61BB2B1A244A185D009F3F56 /* PerformancePreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformancePreset.swift; sourceTree = "<group>"; };
61C3637F2436164B00C4D4E6 /* ObjcExceptionHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjcExceptionHandlerTests.swift; sourceTree = "<group>"; };
Expand All @@ -257,9 +260,9 @@
9E36D92124373EA700BFBDB7 /* SwiftExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftExtensionsTests.swift; sourceTree = "<group>"; };
9E4195742449D739000AB0DB /* app-target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "app-target.xcconfig"; sourceTree = "<group>"; };
9E4195752449D739000AB0DB /* unit-tests-target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "unit-tests-target.xcconfig"; sourceTree = "<group>"; };
9E58E8DE24615B89008E5063 /* ISO8601DateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ISO8601DateFormatter.swift; sourceTree = "<group>"; };
9E58E8DE24615B89008E5063 /* DateFormatting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateFormatting.swift; sourceTree = "<group>"; };
9E58E8E024615C75008E5063 /* JSONEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONEncoder.swift; sourceTree = "<group>"; };
9E58E8E224615EDA008E5063 /* EncodingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncodingTests.swift; sourceTree = "<group>"; };
9E58E8E224615EDA008E5063 /* JSONEncoderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONEncoderTests.swift; sourceTree = "<group>"; };
9E68FB53244707FD0013A8AA /* ObjcExceptionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjcExceptionHandler.m; sourceTree = "<group>"; };
9E68FB54244707FD0013A8AA /* ObjcExceptionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjcExceptionHandler.h; sourceTree = "<group>"; };
9E9EB37624468CE90002C80B /* Datadog.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = Datadog.modulemap; sourceTree = "<group>"; };
Expand Down Expand Up @@ -378,7 +381,7 @@
isa = PBXGroup;
children = (
61133BA02423979B00786299 /* EncodableValue.swift */,
9E58E8DE24615B89008E5063 /* ISO8601DateFormatter.swift */,
9E58E8DE24615B89008E5063 /* DateFormatting.swift */,
9E58E8E024615C75008E5063 /* JSONEncoder.swift */,
);
path = Utils;
Expand Down Expand Up @@ -579,6 +582,7 @@
isa = PBXGroup;
children = (
61345612244756E300E7DA6B /* PerformancePresetTests.swift */,
618C365D248E858200520CDE /* Utils */,
61133C222423990D00786299 /* System */,
61133C272423990D00786299 /* Persistence */,
61133C2E2423990D00786299 /* Upload */,
Expand Down Expand Up @@ -635,7 +639,6 @@
children = (
61133C362423990D00786299 /* InternalLoggersTests.swift */,
9E36D92124373EA700BFBDB7 /* SwiftExtensionsTests.swift */,
9E58E8E224615EDA008E5063 /* EncodingTests.swift */,
);
path = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -694,6 +697,15 @@
name = Frameworks;
sourceTree = "<group>";
};
618C365D248E858200520CDE /* Utils */ = {
isa = PBXGroup;
children = (
618C365E248E85B400520CDE /* DateFormattingTests.swift */,
9E58E8E224615EDA008E5063 /* JSONEncoderTests.swift */,
);
path = Utils;
sourceTree = "<group>";
};
61C3637E2436163400C4D4E6 /* DatadogPrivate */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1023,7 +1035,7 @@
61133BE62423979B00786299 /* LogSanitizer.swift in Sources */,
61133BDF2423979B00786299 /* SwiftExtensions.swift in Sources */,
61133BEA2423979B00786299 /* LogConsoleOutput.swift in Sources */,
9E58E8DF24615B89008E5063 /* ISO8601DateFormatter.swift in Sources */,
9E58E8DF24615B89008E5063 /* DateFormatting.swift in Sources */,
61133BE32423979B00786299 /* UserInfo.swift in Sources */,
61133BE02423979B00786299 /* Datadog.swift in Sources */,
61133BCB2423979B00786299 /* CarrierInfoProvider.swift in Sources */,
Expand Down Expand Up @@ -1058,6 +1070,7 @@
61133C662423990D00786299 /* LogSanitizerTests.swift in Sources */,
61C36470243B5C8300C4D4E6 /* ServerMock.swift in Sources */,
61133C5D2423990D00786299 /* DataUploadConditionsTests.swift in Sources */,
618C365F248E85B400520CDE /* DateFormattingTests.swift in Sources */,
61133C5A2423990D00786299 /* FileTests.swift in Sources */,
61133C512423990D00786299 /* DatadogMocks.swift in Sources */,
61133C6B2423990D00786299 /* LogMatcher.swift in Sources */,
Expand All @@ -1078,7 +1091,7 @@
61133C6A2423990D00786299 /* DatadogTests.swift in Sources */,
61133C5E2423990D00786299 /* LogsUploadDelayTests.swift in Sources */,
61133C5C2423990D00786299 /* DataUploadWorkerTests.swift in Sources */,
9E58E8E324615EDA008E5063 /* EncodingTests.swift in Sources */,
9E58E8E324615EDA008E5063 /* JSONEncoderTests.swift in Sources */,
61133C692423990D00786299 /* LogFileOutputTests.swift in Sources */,
61133C682423990D00786299 /* LogUtilityOutputsTests.swift in Sources */,
61133C6E2423990D00786299 /* DatadogExtensions.swift in Sources */,
Expand Down Expand Up @@ -1120,6 +1133,7 @@
buildActionMask = 2147483647;
files = (
9EF49F1024476D96004F2CA0 /* BenchmarkTests.swift in Sources */,
61D45807248A667600A7F284 /* DateFormatting.swift in Sources */,
9EF49F1124476D96004F2CA0 /* IntegrationTests.swift in Sources */,
9EF49F1224476D96004F2CA0 /* LoggingBenchmarkTests.swift in Sources */,
9EA6A539244897A900621535 /* LoggingIOBenchmarkTests.swift in Sources */,
Expand Down
42 changes: 42 additions & 0 deletions Sources/Datadog/Core/Utils/DateFormatting.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2019-2020 Datadog, Inc.
*/

import Foundation

internal protocol DateFormatterType {
func string(from date: Date) -> String
}

extension ISO8601DateFormatter: DateFormatterType {}
extension DateFormatter: DateFormatterType {}

/// Date formatter producing `ISO8601` string representation of a given date.
/// Should be used to encode dates in messages send to the server.
internal let iso8601DateFormatter: DateFormatterType = {
// As there is a known crash in iOS 11.0 and 11.1 when using `.withFractionalSeconds` option in `ISO8601DateFormatter`,
// we use different `DateFormatterType` implementation depending on the OS version. The problem was fixed by Apple in iOS 11.2.
if #available(iOS 11.2, *) {
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)
return formatter
} else {
let iso8601Formatter = DateFormatter()
iso8601Formatter.locale = Locale(identifier: "en_US_POSIX")
iso8601Formatter.timeZone = TimeZone(abbreviation: "UTC")! // swiftlint:disable:this force_unwrapping
iso8601Formatter.calendar = Calendar(identifier: .gregorian)
iso8601Formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" // ISO8601 format
return iso8601Formatter
}
}()

/// Date formatter producing string representation of a given date for user-facing features (like console output).
internal func presentationDateFormatter(withTimeZone timeZone: TimeZone = .current) -> DateFormatterType {
let formatter = DateFormatter()
formatter.timeZone = timeZone
formatter.calendar = Calendar(identifier: .gregorian)
formatter.dateFormat = "HH:mm:ss.SSS"
return formatter
}
26 changes: 0 additions & 26 deletions Sources/Datadog/Core/Utils/ISO8601DateFormatter.swift

This file was deleted.

6 changes: 5 additions & 1 deletion Sources/Datadog/Core/Utils/JSONEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import Foundation
extension JSONEncoder {
static func `default`() -> JSONEncoder {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = ISO8601DateFormatter.encodingStrategy
encoder.dateEncodingStrategy = .custom { date, encoder in
var container = encoder.singleValueContainer()
let formatted = iso8601DateFormatter.string(from: date)
try container.encode(formatted)
}
if #available(iOS 13.0, OSX 10.15, *) {
encoder.outputFormatting = [.withoutEscapingSlashes]
}
Expand Down
6 changes: 4 additions & 2 deletions Sources/Datadog/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,8 @@ public class Logger {
),
LogConsoleOutput(
logBuilder: logBuilder,
format: format
format: format,
timeZone: .current
)
]
)
Expand All @@ -379,7 +380,8 @@ public class Logger {
case (false, let format?):
return LogConsoleOutput(
logBuilder: logBuilder,
format: format
format: format,
timeZone: .current
)
case (false, nil):
return NoOpLogOutput()
Expand Down
29 changes: 9 additions & 20 deletions Sources/Datadog/Logs/LogOutputs/LogConsoleOutput.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,21 @@ internal protocol ConsoleLogFormatter {

/// `LogOutput` which prints logs to console.
internal struct LogConsoleOutput: LogOutput {
/// Time formatter used for `.short` output format.
static func shortTimeFormatter(calendar: Calendar = .current, timeZone: TimeZone = .current) -> Formatter {
let formatter = ISO8601DateFormatter.default()
if #available(iOS 11.2, *) {
formatter.formatOptions = [.withFractionalSeconds, .withFullTime]
} else {
formatter.formatOptions = [.withFullTime]
}
return formatter
}

private let logBuilder: LogBuilder
private let formatter: ConsoleLogFormatter
private let printingFunction: (String) -> Void

init(
logBuilder: LogBuilder,
format: Logger.Builder.ConsoleLogFormat,
printingFunction: @escaping (String) -> Void = { consolePrint($0) },
timeFormatter: Formatter = LogConsoleOutput.shortTimeFormatter()
timeZone: TimeZone,
printingFunction: @escaping (String) -> Void = { consolePrint($0) }
) {
switch format {
case .short:
self.formatter = ShortLogFormatter(timeFormatter: timeFormatter)
self.formatter = ShortLogFormatter(timeZone: timeZone)
case .shortWith(let prefix):
self.formatter = ShortLogFormatter(timeFormatter: timeFormatter, prefix: prefix)
self.formatter = ShortLogFormatter(timeZone: timeZone, prefix: prefix)
case .json:
self.formatter = JSONLogFormatter()
case .jsonWith(let prefix):
Expand Down Expand Up @@ -80,17 +69,17 @@ private struct JSONLogFormatter: ConsoleLogFormatter {

/// Formats log as custom short string.
private struct ShortLogFormatter: ConsoleLogFormatter {
private let timeFormatter: Formatter
private let timeFormatter: DateFormatterType
private let prefix: String

init(timeFormatter: Formatter, prefix: String = "") {
self.timeFormatter = timeFormatter
init(timeZone: TimeZone, prefix: String = "") {
self.timeFormatter = presentationDateFormatter(withTimeZone: timeZone)
self.prefix = prefix
}

func format(log: Log) -> String {
let time = timeFormatter.string(for: log.date)
let time = timeFormatter.string(from: log.date)
let status = log.status.rawValue.uppercased()
return "\(prefix)\(time ?? "null") [\(status)] \(log.message)"
return "\(prefix)\(time) [\(status)] \(log.message)"
}
}
12 changes: 6 additions & 6 deletions Sources/Datadog/Utils/InternalLoggers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ internal var userLogger = createSDKUserLogger()
internal func createSDKDeveloperLogger(
consolePrintFunction: @escaping (String) -> Void = { consolePrint($0) },
dateProvider: DateProvider = SystemDateProvider(),
timeFormatter: Formatter = LogConsoleOutput.shortTimeFormatter()
timeZone: TimeZone = .current
) -> Logger? {
if CompilationConditions.isSDKCompiledForDevelopment == false {
return nil
Expand All @@ -45,8 +45,8 @@ internal func createSDKDeveloperLogger(
carrierInfoProvider: loggingFeature.carrierInfoProvider
),
format: .shortWith(prefix: "🐶 → "),
printingFunction: consolePrintFunction,
timeFormatter: timeFormatter
timeZone: timeZone,
printingFunction: consolePrintFunction
)

return Logger(logOutput: consoleOutput, identifier: "sdk-developer")
Expand All @@ -55,7 +55,7 @@ internal func createSDKDeveloperLogger(
internal func createSDKUserLogger(
consolePrintFunction: @escaping (String) -> Void = { consolePrint($0) },
dateProvider: DateProvider = SystemDateProvider(),
timeFormatter: Formatter = LogConsoleOutput.shortTimeFormatter()
timeZone: TimeZone = .current
) -> Logger {
guard let loggingFeature = LoggingFeature.instance else {
return Logger(logOutput: NoOpLogOutput(), identifier: "no-op")
Expand All @@ -73,8 +73,8 @@ internal func createSDKUserLogger(
carrierInfoProvider: loggingFeature.carrierInfoProvider
),
format: .shortWith(prefix: "[DATADOG SDK] 🐶 → "),
printingFunction: consolePrintFunction,
timeFormatter: timeFormatter
timeZone: timeZone,
printingFunction: consolePrintFunction
)

return Logger(
Expand Down
Loading

0 comments on commit 1e84928

Please sign in to comment.