Skip to content

Commit e1acb39

Browse files
committed
added unit tests and fixed bugs
1 parent f3e5bea commit e1acb39

18 files changed

+723
-58
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//
2+
// Copyright The OpenTelemetry Authors
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
6+
import Foundation
7+
import OpenTelemetryApi
8+
9+
class ComponentRegistry<T> {
10+
private var lock = Lock()
11+
private var componentByName = [String: T]()
12+
private var componentByNameVersion = [String: [String: T]]()
13+
private var componentByNameSchema = [String: [String: T]]()
14+
private var componentByNameVersionSchema = [ String: [String : [String: T]]]()
15+
private var allComponents = [T]()
16+
17+
private let builder : (InstrumentationScopeInfo) -> T
18+
19+
init(_ builder : @escaping (InstrumentationScopeInfo) -> T){
20+
self.builder = builder
21+
22+
}
23+
24+
public func get(name: String, version: String? = nil, schemaUrl : String? = nil) -> T {
25+
lock.lock()
26+
defer {
27+
lock.unlock()
28+
}
29+
if let version = version, let schemaUrl = schemaUrl {
30+
if componentByNameVersionSchema[name] == nil {
31+
componentByNameVersionSchema[name] = [String: [String: T]]()
32+
}
33+
34+
if componentByNameVersionSchema[name]![version] == nil {
35+
componentByNameVersionSchema[name]![version] = [String:T]()
36+
}
37+
38+
if componentByNameVersionSchema[name]![version]![schemaUrl] == nil {
39+
componentByNameVersionSchema[name]![version]![schemaUrl] = buildComponent(InstrumentationScopeInfo(name: name, version:version, schemaUrl: schemaUrl))
40+
}
41+
return componentByNameVersionSchema[name]![version]![schemaUrl]!
42+
} else if let version = version {
43+
if componentByNameVersion[name] == nil {
44+
componentByNameVersion[name] = [String: T]()
45+
}
46+
47+
if componentByNameVersion[name]![version] == nil {
48+
componentByNameVersion[name]![version] = buildComponent(InstrumentationScopeInfo(name:name, version:version))
49+
}
50+
51+
return componentByNameVersion[name]![version]!
52+
53+
} else if let schemaUrl = schemaUrl {
54+
if componentByNameSchema[name] == nil {
55+
componentByNameSchema[name] = [String:T]()
56+
}
57+
58+
if componentByNameSchema[name]![schemaUrl] == nil {
59+
componentByNameSchema[name]![schemaUrl] = buildComponent(InstrumentationScopeInfo(name: name, schemaUrl: schemaUrl))
60+
}
61+
62+
return componentByNameSchema[name]![schemaUrl]!
63+
64+
} else {
65+
if componentByName[name] == nil {
66+
componentByName[name] = buildComponent(InstrumentationScopeInfo(name: name))
67+
}
68+
return componentByName[name]!
69+
}
70+
}
71+
72+
private func buildComponent(_ scope: InstrumentationScopeInfo) -> T {
73+
let component = builder(scope)
74+
allComponents.append(component)
75+
return component
76+
}
77+
78+
public func getComponents() -> [T] {
79+
return [T](allComponents)
80+
}
81+
}

Sources/OpenTelemetrySdk/Logs/ComponentRegistry.swift

Lines changed: 0 additions & 48 deletions
This file was deleted.

Sources/OpenTelemetrySdk/Logs/Export/InMemoryLogRecordExporter.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ public class InMemoryLogRecordExporter : LogRecordExporter {
99
private var finishedLogRecords = [ReadableLogRecord]()
1010
private var isRunning = true
1111

12+
public func getFinishedLogRecords() -> [ReadableLogRecord] {
13+
return finishedLogRecords
14+
}
15+
1216
public func export(logRecords: [ReadableLogRecord]) -> ExportResult {
1317
guard isRunning else {
1418
return .failure
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// Copyright The OpenTelemetry Authors
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
6+
import Foundation
7+
8+
public class MultiLogRecordExporter : LogRecordExporter {
9+
var logRecordExporters : [LogRecordExporter]
10+
11+
public init(logRecordExporters: [LogRecordExporter]) {
12+
self.logRecordExporters = logRecordExporters
13+
}
14+
15+
public func export(logRecords: [ReadableLogRecord]) -> ExportResult {
16+
var result = ExportResult.success
17+
logRecordExporters.forEach {
18+
result.mergeResultCode(newResultCode: $0.export(logRecords: logRecords))
19+
}
20+
return result
21+
}
22+
23+
public func shutdown() {
24+
logRecordExporters.forEach {
25+
$0.shutdown()
26+
}
27+
}
28+
29+
public func forceFlush() -> ExportResult {
30+
var result = ExportResult.success
31+
logRecordExporters.forEach {
32+
result.mergeResultCode(newResultCode: $0.forceFlush())
33+
}
34+
return result
35+
}
36+
37+
38+
}

Sources/OpenTelemetrySdk/Logs/LogLimits.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import Foundation
88
public struct LogLimits {
99
static public let defaultMaxAttributeCount = 128
1010
static public let defaultMaxAtributeLength = Int.max
11-
private let maxAttributeCount : Int
12-
private let maxAttributeLength : Int
11+
public let maxAttributeCount : Int
12+
public let maxAttributeLength : Int
1313

1414
public init(maxAttributeCount: Int = Self.defaultMaxAttributeCount , maxAttributeLength: Int = Self.defaultMaxAtributeLength) {
1515
self.maxAttributeCount = maxAttributeCount

Sources/OpenTelemetrySdk/Logs/LogRecordBuilderSdk.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class LogRecordBuilderSdk : EventBuilder {
1919
private var observedTimestamp : Date?
2020
private var body : String?
2121
private var severity: Severity?
22-
private var attributes = [String:AttributeValue]()
22+
private var attributes : AttributesDictionary
2323
private var spanContext : SpanContext?
2424

2525

@@ -29,6 +29,7 @@ public class LogRecordBuilderSdk : EventBuilder {
2929
limits = sharedState.logLimits
3030
self.includeSpanContext = includeSpanContext
3131
self.instrumentationScope = instrumentationScope
32+
attributes = AttributesDictionary(capacity: sharedState.logLimits.maxAttributeCount, valueLengthLimit: sharedState.logLimits.maxAttributeLength)
3233
}
3334

3435
public func setObservedTimestamp(_ observed: Date) -> Self {
@@ -37,7 +38,7 @@ public class LogRecordBuilderSdk : EventBuilder {
3738
}
3839

3940
public func setSpanContext(_ context: OpenTelemetryApi.SpanContext) -> Self {
40-
self.spanContext = spanContext
41+
self.spanContext = context
4142

4243
return self
4344
}
@@ -53,7 +54,7 @@ public class LogRecordBuilderSdk : EventBuilder {
5354
}
5455

5556
public func setAttributes(_ attributes: [String : OpenTelemetryApi.AttributeValue]) -> Self {
56-
self.attributes = attributes
57+
self.attributes.updateValues(attributes: attributes)
5758
return self
5859
}
5960

@@ -72,7 +73,7 @@ public class LogRecordBuilderSdk : EventBuilder {
7273
spanContext: spanContext,
7374
severity: severity,
7475
body: body,
75-
attributes: attributes))
76+
attributes: attributes.attributes))
7677
}
7778

7879

Sources/OpenTelemetrySdk/Logs/LoggerSdk.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class LoggerSdk : OpenTelemetryApi.Logger {
2323
public func eventBuilder(name: String) -> OpenTelemetryApi.EventBuilder {
2424
guard let eventDomain = self.eventDomain else {
2525
os_log("Events cannot be emitted from Logger without an event domain. Use `LoggerBuilder.setEventDomain(_ domain: String) when obtaining a Logger.")
26-
return DefaultLoggerProvider.instance.loggerBuilder(instrumentationScopeName: "unused").setEventDomain("unused").setAttributes(["event.domain": AttributeValue.string("unused"), "event.name": AttributeValue.string(name)]) as! EventBuilder
26+
return DefaultLoggerProvider.instance.loggerBuilder(instrumentationScopeName: "unused").setEventDomain("unused").setAttributes(["event.domain": AttributeValue.string("unused"), "event.name": AttributeValue.string(name)]).build().eventBuilder(name: "unused")
2727
}
2828
return LogRecordBuilderSdk(sharedState: sharedState, instrumentationScope: instrumentationScope, includeSpanContext: true).setAttributes(["event.domain": AttributeValue.string(eventDomain),
2929
"event.name": AttributeValue.string(name)])

Sources/OpenTelemetrySdk/Trace/AttributesDictionary.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ public struct AttributesDictionary {
1212
var attributes: [String: AttributeValue]
1313
var keys: [String]
1414
private var capacity: Int
15+
private var valueLengthLimit : Int
1516
private var recordedAttributes: Int
1617

17-
public init(capacity: Int) {
18+
public init(capacity: Int, valueLengthLimit: Int = Int.max) {
1819
attributes = [String: AttributeValue]()
1920
keys = [String]()
2021
recordedAttributes = 0
22+
self.valueLengthLimit = valueLengthLimit
2123
self.capacity = capacity
2224
}
2325

@@ -35,7 +37,24 @@ public struct AttributesDictionary {
3537
}
3638

3739
@discardableResult public mutating func updateValue(value: AttributeValue, forKey key: String) -> AttributeValue? {
38-
let oldValue = attributes.updateValue(value, forKey: key)
40+
var attributedValue = value
41+
switch value {
42+
case let .string(v):
43+
if v.count > valueLengthLimit {
44+
attributedValue = AttributeValue.string(String(v.prefix(valueLengthLimit)))
45+
}
46+
break
47+
case let .stringArray(v):
48+
var strArr = [String]()
49+
v.forEach { string in
50+
strArr.append(String(string.prefix(valueLengthLimit)))
51+
}
52+
attributedValue = AttributeValue.stringArray(strArr)
53+
break
54+
default:
55+
break
56+
}
57+
let oldValue = attributes.updateValue(attributedValue, forKey: key)
3958
if oldValue == nil {
4059
recordedAttributes += 1
4160
keys.append(key)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// Copyright The OpenTelemetry Authors
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
6+
import Foundation
7+
@testable import OpenTelemetrySdk
8+
import XCTest
9+
10+
class ComponentRegistryTests : XCTestCase {
11+
12+
13+
func testComponentRegistry() {
14+
let registry = ComponentRegistry<String> { instrumentationScope in
15+
return instrumentationScope.name + (instrumentationScope.version ?? "") + (instrumentationScope.schemaUrl ?? "")
16+
}
17+
18+
let item1 = registry.get(name: "one")
19+
let item2 = registry.get(name: "one", version: "1")
20+
let item3 = registry.get(name:"one",version: "1", schemaUrl: "https://opentelemetry.io/schemas/1.15.0")
21+
let item4 = registry.get(name: "one", schemaUrl: "https://opentelemetry.io/schemas/1.15.0")
22+
23+
XCTAssertNotIdentical(item2 as AnyObject, item1 as AnyObject)
24+
XCTAssertNotIdentical(item1 as AnyObject, item3 as AnyObject)
25+
XCTAssertNotIdentical(item2 as AnyObject, item3 as AnyObject)
26+
XCTAssertNotIdentical(item4 as AnyObject, item1 as AnyObject)
27+
XCTAssertNotIdentical(item4 as AnyObject, item2 as AnyObject)
28+
XCTAssertNotIdentical(item4 as AnyObject, item3 as AnyObject)
29+
30+
XCTAssertIdentical(registry.get(name: "one") as AnyObject, item1 as AnyObject)
31+
XCTAssertIdentical(registry.get(name: "one", version: "1") as AnyObject, item2 as AnyObject)
32+
XCTAssertIdentical(registry.get(name:"one",version: "1", schemaUrl: "https://opentelemetry.io/schemas/1.15.0") as AnyObject, item3 as AnyObject)
33+
XCTAssertIdentical(registry.get(name: "one", schemaUrl: "https://opentelemetry.io/schemas/1.15.0") as AnyObject, item4 as AnyObject)
34+
35+
36+
37+
38+
}
39+
}

0 commit comments

Comments
 (0)