Skip to content

Commit

Permalink
core-common: Attributes provide overloaded addOne and added to …
Browse files Browse the repository at this point in the history
…allow optional values
  • Loading branch information
iRevive committed Sep 14, 2024
1 parent 91c49bc commit 3f74d63
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 29 deletions.
54 changes: 54 additions & 0 deletions core/common/src/main/scala/org/typelevel/otel4s/Attributes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,28 @@ sealed trait Attributes
final def added[T: KeySelect](name: String, value: T): Attributes =
added(Attribute(name, value))

/** Adds an [[`Attribute`]] with the given name and value to these `Attributes`, replacing any `Attribute` with the
* same name and type if one exists.
*
* If the `value` is None, the attributes remain intact.
*/
final def added[T: KeySelect](name: String, value: Option[T]): Attributes =
value.fold(this)(added(name, _))

/** Adds an [[`Attribute`]] with the given key and value to these `Attributes`, replacing any `Attribute` with the
* same key if one exists.
*/
final def added[T](key: AttributeKey[T], value: T): Attributes =
added(Attribute(key, value))

/** Adds an [[`Attribute`]] with the given key and value to these `Attributes`, replacing any `Attribute` with the
* same key if one exists.
*
* If the `value` is None, the attributes remain intact.
*/
final def added[T](key: AttributeKey[T], value: Option[T]): Attributes =
value.fold(this)(added(key, _))

/** Adds the given [[`Attribute`]] to these `Attributes`, replacing any `Attribute` with the same key if one exists.
*/
def added(attribute: Attribute[_]): Attributes
Expand Down Expand Up @@ -210,6 +226,44 @@ object Attributes extends SpecificIterableFactory[Attribute[_], Attributes] {
this
}

/** Adds the attribute with the given `key` and `value` (if any) to the builder.
*
* @note
* no attribute will be added or overwritten if the `value` is None.
*
* @note
* if the given `key` is already present in the builder, the value will be overwritten with the given `value`.
*
* @param key
* the key of the attribute. Denotes the types of the `value`
*
* @param value
* the value of the attribute
*/
def addOne[A](key: AttributeKey[A], value: Option[A]): this.type = {
value.foreach(v => addOne(key, v))
this
}

/** Adds the attribute with the given `key` (created from `name`) and `value` (if any) to the builder.
*
* @note
* no attribute will be added or overwritten if the `value` is None.
*
* @note
* if the given `key` is already present in the builder, the value will be overwritten with the given `value`.
*
* @param name
* the name of the attribute's key
*
* @param value
* the value of the attribute
*/
def addOne[A: KeySelect](name: String, value: Option[A]): this.type = {
value.foreach(v => addOne(name, v))
this
}

/** Adds the given `attribute` to the builder.
*
* @note
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ private class AWSBeanstalkDetector[F[_]: Concurrent: Files: Console] private (
builder.addOne(Keys.CloudProvider, Const.CloudProvider)
builder.addOne(Keys.CloudPlatform, Const.CloudPlatform)

metadata.deploymentId.foreach(id => builder.addOne(Keys.ServiceInstanceId, id.toString))
metadata.versionLabel.foreach(v => builder.addOne(Keys.ServiceVersion, v))
metadata.environmentName.foreach(n => builder.addOne(Keys.ServiceNamespace, n))
builder.addOne(Keys.ServiceInstanceId, metadata.deploymentId.map(_.toString))
builder.addOne(Keys.ServiceVersion, metadata.versionLabel)
builder.addOne(Keys.ServiceNamespace, metadata.environmentName)

TelemetryResource(builder.result(), Some(SchemaUrls.Current))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ private class AWSECSDetector[F[_]: Async: Network: Env: Console] private (
builder.addOne(Keys.CloudPlatform, Const.CloudPlatform)
builder.addOne(Keys.CloudResourceId, container.containerArn)
builder.addOne(Keys.CloudAvailabilityZones, task.availabilityZone)
regionOpt.foreach(region => builder.addOne(Keys.CloudRegion, region))
accountIdOpt.foreach(accountId => builder.addOne(Keys.CloudAccountId, accountId))
builder.addOne(Keys.CloudRegion, regionOpt)
builder.addOne(Keys.CloudAccountId, accountIdOpt)

// container
builder.addOne(Keys.ContainerId, container.dockerId)
builder.addOne(Keys.ContainerName, container.dockerName)
imageNameOpt.foreach(name => builder.addOne(Keys.ContainerImageName, name))
imageTagOpt.foreach(tag => builder.addOne(Keys.ContainerImageTags, Seq(tag)))
builder.addOne(Keys.ContainerImageName, imageNameOpt)
builder.addOne(Keys.ContainerImageTags, imageTagOpt.map(Seq(_)))

// aws
builder.addOne(Keys.AwsLogGroupNames, Seq(container.logOptions.group))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ private class AWSLambdaDetector[F[_]: Env: Monad] extends TelemetryResourceDetec
builder.addOne(Keys.CloudProvider, Const.CloudProvider)
builder.addOne(Keys.CloudPlatform, Const.CloudPlatform)

region.foreach(r => builder.addOne(Keys.CloudRegion, r))
functionName.foreach(name => builder.addOne(Keys.FaasName, name))
functionVersion.foreach(v => builder.addOne(Keys.FaasVersion, v))
builder.addOne(Keys.CloudRegion, region)
builder.addOne(Keys.FaasName, functionName)
builder.addOne(Keys.FaasVersion, functionVersion)

TelemetryResource(builder.result(), Some(SchemaUrls.Current))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ private[resource] trait HostDetectorPlatform { self: HostDetector.type =>

def detect: F[Option[TelemetryResource]] =
for {
hostOpt <- Sync[F]
.blocking(InetAddress.getLocalHost.getHostName)
.redeem(_ => None, Some(_))

archOpt <- Sync[F].delay(sys.props.get("os.arch"))
host <- Sync[F].blocking(InetAddress.getLocalHost.getHostName).redeem(_ => None, Some(_))
arch <- Sync[F].delay(sys.props.get("os.arch"))
} yield {
val host = hostOpt.map(Keys.Host(_))
val arch = archOpt.map(Keys.Arch(_))
val attributes = host.to(Attributes) ++ arch.to(Attributes)
val builder = Attributes.newBuilder

builder.addOne(Keys.Host, host)
builder.addOne(Keys.Arch, arch)

val attributes = builder.result()

Option.when(attributes.nonEmpty)(
TelemetryResource(attributes, Some(SchemaUrls.Current))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private[resource] trait ProcessDetectorPlatform { self: ProcessDetector.type =>
} yield {
val builder = Attributes.newBuilder

getPid(runtime).foreach(pid => builder.addOne(Keys.Pid(pid)))
builder.addOne(Keys.Pid, getPid(runtime))

javaHomeOpt.foreach { javaHome =>
val exePath = executablePath(javaHome, osNameOpt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ private[resource] trait ProcessRuntimeDetectorPlatform {
} yield {
val attributes = Attributes.newBuilder

runtimeName.foreach(name => attributes.addOne(Keys.Name(name)))
runtimeVersion.foreach(name => attributes.addOne(Keys.Version(name)))
(vmVendor, vmName, vmVersion).mapN { (vendor, name, version) =>
attributes.addOne(Keys.Description(s"$vendor $name $version"))
}
val description =
(vmVendor, vmName, vmVersion).mapN { (vendor, name, version) =>
s"$vendor $name $version"
}

attributes.addOne(Keys.Name, runtimeName)
attributes.addOne(Keys.Version, runtimeVersion)
attributes.addOne(Keys.Description, description)

Some(TelemetryResource(attributes.result(), Some(SchemaUrls.Current)))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ private[resource] trait HostDetectorPlatform { self: HostDetector.type =>

def detect: F[Option[TelemetryResource]] =
for {
hostOpt <- Sync[F].delay(detectHost).handleError(_ => None)
archOpt <- Sync[F].delay(sys.props.get("os.arch"))
host <- Sync[F].delay(detectHost).handleError(_ => None)
arch <- Sync[F].delay(sys.props.get("os.arch"))
} yield {
val host = hostOpt.map(Keys.Host(_))
val arch = archOpt.map(Keys.Arch(_))
val attributes = host.to(Attributes) ++ arch.to(Attributes)
val builder = Attributes.newBuilder

builder.addOne(Keys.Host, host)
builder.addOne(Keys.Arch, arch)

val attributes = builder.result()

Option.when(attributes.nonEmpty)(
TelemetryResource(attributes, Some(SchemaUrls.Current))
)
Expand Down

0 comments on commit 3f74d63

Please sign in to comment.