Skip to content

Commit

Permalink
Update attribute processor for stable metrics
Browse files Browse the repository at this point in the history
Previously AttribtueProcessor is a class and not open. It can't be
customized externally. Now it's changed to procotol and its static
functions are moved into SimpleAttributeProcessor (now it's public).

Also duplicated NoopAttributesProcessor is removed and more tests are
added.
  • Loading branch information
yangjian committed Mar 8, 2024
1 parent 812e3fc commit 6e5ad4b
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 70 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,87 +6,80 @@
import Foundation
import OpenTelemetryApi

public protocol AttributeProcessorProtocol {
public protocol AttributeProcessor {
func process(incoming : [String: AttributeValue]) -> [String: AttributeValue]
}
public class AttributeProcessor : AttributeProcessorProtocol {
public func then(other : AttributeProcessor) -> AttributeProcessor {

public extension AttributeProcessor {
func then(other : AttributeProcessor) -> AttributeProcessor {
if type(of: other) == NoopAttributeProcessor.self {
return self
}
if type(of: self) == NoopAttributeProcessor.self {
return other
}

if type(of: other) == JoinedAttributeProcessor.self {
return (other as! JoinedAttributeProcessor).prepend(processor:self)
if let joined = self as? JoinedAttributeProcessor {
return joined.append(processor:other)

Check warning on line 23 in Sources/OpenTelemetrySdk/Metrics/Stable/View/AttributeProcessor.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenTelemetrySdk/Metrics/Stable/View/AttributeProcessor.swift#L23

Added line #L23 was not covered by tests
}
if let joined = other as? JoinedAttributeProcessor {
return joined.prepend(processor:self)

Check warning on line 26 in Sources/OpenTelemetrySdk/Metrics/Stable/View/AttributeProcessor.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenTelemetrySdk/Metrics/Stable/View/AttributeProcessor.swift#L26

Added line #L26 was not covered by tests
}

return JoinedAttributeProcessor([self, other])
}
}

public class SimpleAttributeProcessor : AttributeProcessor {
let attributeProcessor : ([String: AttributeValue]) -> [String:AttributeValue]

init(attributeProcessor : @escaping ([String: AttributeValue]) -> [String: AttributeValue]) {
self.attributeProcessor = attributeProcessor
}

public func process(incoming: [String : AttributeValue]) -> [String : AttributeValue] {
return incoming
return attributeProcessor(incoming)
}

public static func filterByKeyName( nameFilter : @escaping (String) -> Bool) -> AttributeProcessor {
static func filterByKeyName( nameFilter : @escaping (String) -> Bool) -> AttributeProcessor {
return SimpleAttributeProcessor { attributes in
attributes.filter { key, value in
nameFilter(key)
}
}
}

public static func append(attributes: [String : AttributeValue]) -> AttributeProcessor {
static func append(attributes: [String : AttributeValue]) -> AttributeProcessor {
SimpleAttributeProcessor { incoming in
incoming.merging(attributes) { a, b in
b
}
}
}


}

internal class SimpleAttributeProcessor : AttributeProcessor {

let attributeProcessor : ([String: AttributeValue]) -> [String:AttributeValue]

init(attributeProcessor : @escaping ([String: AttributeValue]) -> [String: AttributeValue]) {
self.attributeProcessor = attributeProcessor

}

override func process(incoming: [String : OpenTelemetryApi.AttributeValue]) -> [String : OpenTelemetryApi.AttributeValue] {
return attributeProcessor(incoming)
}


}


public class JoinedAttributeProcessor : AttributeProcessor {

override public func process(incoming: [String : OpenTelemetryApi.AttributeValue]) -> [String : OpenTelemetryApi.AttributeValue] {
public func process(incoming: [String : AttributeValue]) -> [String : AttributeValue] {
var result = incoming
for processor in processors {
result = processor.process(incoming: result)
}
return result
}

override public func then(other: AttributeProcessor) -> AttributeProcessor {
public func append(processor: AttributeProcessor) -> JoinedAttributeProcessor {
var newList = processors
if let otherJoined = other as? JoinedAttributeProcessor {
newList.append(contentsOf: otherJoined.processors)
if let joinedProcessor = processor as? JoinedAttributeProcessor {
newList.append(contentsOf: joinedProcessor.processors)

Check warning on line 75 in Sources/OpenTelemetrySdk/Metrics/Stable/View/AttributeProcessor.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenTelemetrySdk/Metrics/Stable/View/AttributeProcessor.swift#L75

Added line #L75 was not covered by tests
} else {
newList.append(other)
newList.append(processor)
}
return JoinedAttributeProcessor(newList)
}

public func prepend(processor: AttributeProcessor) -> AttributeProcessor {
public func prepend(processor: AttributeProcessor) -> JoinedAttributeProcessor {
var newProcessors = [processor]
newProcessors.append(contentsOf: processors)
return JoinedAttributeProcessor(newProcessors)
Expand All @@ -101,8 +94,8 @@ public class JoinedAttributeProcessor : AttributeProcessor {

public class NoopAttributeProcessor : AttributeProcessor {
static let noop = NoopAttributeProcessor()
private override init() {}
override public func process(incoming: [String : AttributeValue]) -> [String : AttributeValue] {
private init() {}
public func process(incoming: [String : AttributeValue]) -> [String : AttributeValue] {
return incoming
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ public class ViewBuilder {
return self
}

public func withAttributeProcessor(processor: AttributeProcessor) -> Self {
self.processor = processor
return self
}

Check warning on line 36 in Sources/OpenTelemetrySdk/Metrics/Stable/View/ViewBuilder.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenTelemetrySdk/Metrics/Stable/View/ViewBuilder.swift#L33-L36

Added lines #L33 - L36 were not covered by tests

public func addAttributeFilter(keyFilter: @escaping (String) -> Bool) -> Self {
addAttributeProcessor(processor: AttributeProcessor.filterByKeyName(nameFilter: keyFilter))
addAttributeProcessor(processor: SimpleAttributeProcessor.filterByKeyName(nameFilter: keyFilter))

Check warning on line 39 in Sources/OpenTelemetrySdk/Metrics/Stable/View/ViewBuilder.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenTelemetrySdk/Metrics/Stable/View/ViewBuilder.swift#L39

Added line #L39 was not covered by tests
}

public func addAttributeProcessor(processor: AttributeProcessor) -> Self {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
//

import Foundation

import OpenTelemetryApi
@testable import OpenTelemetrySdk
import XCTest

class AttributeProcessorTests : XCTestCase {
func testStaticNoop() {
XCTAssertNotNil(NoopAttributeProcessor.noop)
XCTAssertEqual(NoopAttributeProcessor.noop.process(incoming: ["hello": AttributeValue.string("world")]), ["hello" : AttributeValue.string("world")])
}

func testSimpleProcessor() {
let incoming = ["hello": AttributeValue("world")]

var processor: AttributeProcessor = SimpleAttributeProcessor.append(attributes: ["foo" : .string("bar")])
XCTAssertEqual(processor.process(incoming: incoming), ["hello" : .string("world"), "foo": .string("bar")])

processor = processor.then(other: SimpleAttributeProcessor.filterByKeyName(nameFilter: { $0 == "foo" }))
XCTAssertEqual(processor.process(incoming: incoming), ["foo": .string("bar")])
}

func testJoinedProcessor() {
let incoming = ["hello": AttributeValue("world")]

let processor0 = SimpleAttributeProcessor.append(attributes: ["foo" : .string("bar0")])
let processor1 = SimpleAttributeProcessor.append(attributes: ["foo" : .string("bar1")])
let processor2 = SimpleAttributeProcessor.append(attributes: ["foo" : .string("bar2")])

var processor = JoinedAttributeProcessor([processor0])
XCTAssertEqual(processor.process(incoming: incoming), ["hello" : .string("world"), "foo": .string("bar0")])

processor = processor.prepend(processor: processor1)
XCTAssertEqual(processor.process(incoming: incoming), ["hello" : .string("world"), "foo": .string("bar0")])

processor = processor.append(processor: processor2)
XCTAssertEqual(processor.process(incoming: incoming), ["hello" : .string("world"), "foo": .string("bar2")])
}
}

This file was deleted.

0 comments on commit 6e5ad4b

Please sign in to comment.