Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.opentelemetry.android.instrumentation.activity.startup.AppStartupTimer
import io.opentelemetry.android.instrumentation.common.ActiveSpan
import io.opentelemetry.android.semconv.ActivityAttributes.ACTIVITY_NAME_KEY
import io.opentelemetry.android.semconv.StartAttributes.START_TYPE_KEY
import io.opentelemetry.android.semconv.StartAttributes.StartTypeValues
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
Expand Down Expand Up @@ -51,7 +52,7 @@ internal class ActivityTracer(
return createSpanWithParent("Created", appStartupTimer.startupSpan)
}
if (activityName == initialAppActivity) {
return createAppStartSpan("warm")
return createAppStartSpan(StartTypeValues.WARM.value)
}
return createSpan("Created")
}
Expand All @@ -69,7 +70,7 @@ internal class ActivityTracer(
// Note: in a multi-activity application, navigating back to the first activity can trigger
// this, so it would not be ideal to call it an AppStart.
if (!multiActivityApp && activityName == initialAppActivity) {
return createAppStartSpan("hot")
return createAppStartSpan(StartTypeValues.HOT.value)
}
return createSpan("Restarted")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.util.Log
import io.opentelemetry.android.common.RumConstants
import io.opentelemetry.android.internal.services.visiblescreen.activities.DefaultingActivityLifecycleCallbacks
import io.opentelemetry.android.semconv.StartAttributes.START_TYPE_KEY
import io.opentelemetry.android.semconv.StartAttributes.StartTypeValues
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.sdk.common.Clock
Expand Down Expand Up @@ -47,7 +48,7 @@ internal class AppStartupTimer {
tracer
.spanBuilder("AppStart")
.setStartTimestamp(firstPossibleTimestamp, TimeUnit.NANOSECONDS)
.setAttribute(START_TYPE_KEY, "cold")
.setAttribute(START_TYPE_KEY, StartTypeValues.COLD.value)
.startSpan()
this.startupSpan = appStart
return appStart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.instrumentation.library.okhttp.websocket.internal

import io.opentelemetry.android.semconv.WebsocketAttributes.WebsocketMessageTypeValues
import io.opentelemetry.android.semconv.events.WebsocketCloseEvent
import io.opentelemetry.android.semconv.events.WebsocketErrorEvent
import io.opentelemetry.android.semconv.events.WebsocketMessageEvent
Expand Down Expand Up @@ -49,7 +50,7 @@ class WebsocketListenerWrapper(
val attributes = extractAttributes(webSocket)
WebsocketMessageEvent(
websocketMessageSize = text.length.toLong(),
websocketMessageType = "text",
websocketMessageType = WebsocketMessageTypeValues.TEXT.value,
).emit(logger, attributes)
delegate.onMessage(webSocket, text)
}
Expand All @@ -61,7 +62,7 @@ class WebsocketListenerWrapper(
val attributes = extractAttributes(webSocket)
WebsocketMessageEvent(
websocketMessageSize = bytes.size.toLong(),
websocketMessageType = "bytes",
websocketMessageType = WebsocketMessageTypeValues.BYTES.value,
).emit(logger, attributes)
delegate.onMessage(webSocket, bytes)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.content.Context
import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import io.opentelemetry.android.semconv.ScreenAttributes.ScreenOrientationValues
import io.opentelemetry.android.semconv.events.DeviceScreenOrientationEvent
import io.opentelemetry.api.logs.Logger

Expand All @@ -36,9 +37,9 @@ internal class ScreenOrientationDetector(
private val Int.name: String
get() {
return when (this) {
ORIENTATION_LANDSCAPE -> "landscape"
ORIENTATION_PORTRAIT -> "portrait"
else -> "undefined"
ORIENTATION_LANDSCAPE -> ScreenOrientationValues.LANDSCAPE.value
ORIENTATION_PORTRAIT -> ScreenOrientationValues.PORTRAIT.value
else -> ScreenOrientationValues.UNDEFINED.value
}
}

Expand Down
44 changes: 38 additions & 6 deletions semconv/model/android/registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,47 @@ groups:
The current application screen name used by the Android SDK.
examples: ["user.login", "Cart"]
- id: screen.orientation
type: string
type:
members:
- id: portrait
value: "portrait"
stability: development
brief: The screen is in portrait orientation.
- id: landscape
value: "landscape"
stability: development
brief: The screen is in landscape orientation.
- id: undefined
value: "undefined"
stability: development
brief: The screen orientation could not be determined.
stability: development
brief: >
The Android screen orientation.
examples: ["portrait", "landscape", "undefined"]
- id: span.exporter
type: string
stability: development
brief: >
A string representation of the span exporter configured during SDK initialization.
examples: ["OtlpHttpSpanExporter"]
- id: start.type
type: string
type:
members:
- id: cold
value: "cold"
stability: development
brief: The application started from scratch, with no process or activity reused.
- id: warm
value: "warm"
stability: development
brief: The application process was reused but the activity had to be recreated.
- id: hot
value: "hot"
stability: development
brief: The application and its activity were already in memory and brought to the foreground.
stability: development
brief: >
The application start type.
examples: ["cold", "warm", "hot"]
- id: storage.free
type: int
stability: development
Expand All @@ -139,8 +163,16 @@ groups:
The size of a WebSocket message payload.
examples: [128]
- id: websocket.message.type
type: string
type:
members:
- id: text
value: "text"
stability: development
brief: A text message.
- id: bytes
value: "bytes"
stability: development
brief: A binary message.
stability: development
brief: >
The WebSocket message payload type.
examples: ["text", "bytes"]
13 changes: 12 additions & 1 deletion semconv/templates/registry/kotlin/kotlin_event_template.kt.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@

package io.opentelemetry.android.semconv.events

{%- set has_array_attributes = (ctx.attributes | selectattr("type", "in", ["string[]", "boolean[]", "int[]", "double[]"]) | list | length) > 0 -%}
{%- if has_array_attributes %}
import io.opentelemetry.api.common.AttributeKey
{%- endif %}
import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.logs.Logger

// Autogenerated OpenTelemetry Android semantic convention event for '{{ctx.name}}'.
// Autogenerated OpenTelemetry Android semantic convention event for '{{ ctx.name }}'.
//
// DO NOT EDIT - AUTOGENERATED FILE
{{ [ctx.brief, concat_if("\n\nNotes:\n\n", ctx.note)] | comment }}
Expand All @@ -30,7 +34,14 @@ class {{ my_class_name }}(
val attributes = Attributes.builder()
{%- for attribute in ctx.attributes %}
{%- set required = attribute.requirement_level == "required" %}
{%- if attribute.type in ["string[]", "boolean[]", "int[]", "double[]"] %}
{%- set key = 'AttributeKey.' ~ (attribute.type | map_text("kotlin_key_factory")) ~ '("' ~ attribute.name ~ '")' %}
{%- if required %}
attributes.put({{ key }}, {{ attribute.name | camel_case }})
{%- else %}
{{ attribute.name | camel_case }}?.let { attributes.put({{ key }}, it) }
{%- endif %}
{%- elif required %}
attributes.put("{{ attribute.name }}", {{ attribute.name | camel_case }})
{%- else %}
{{ attribute.name | camel_case }}?.let { attributes.put("{{ attribute.name }}", it) }
Expand Down
35 changes: 23 additions & 12 deletions semconv/templates/registry/kotlin/kotlin_semconv_template.kt.j2
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,30 @@ object {{ my_class_name }} {
@Deprecated("{{ attribute.deprecated.note | replace('\n', ' ') | trim }}")
{%- endif %}
const val {{ attribute.name | screaming_snake_case }}: String = "{{ attribute.name }}"
{%- if attribute.type != "any" %}
{%- set itype = attribute.type | instantiated_type %}
{%- if itype in ["string", "boolean", "int", "double", "string[]", "boolean[]", "int[]", "double[]"] %}
@JvmField
{%- if attribute.type == "string" %}
val {{ attribute.name | screaming_snake_case }}_KEY: AttributeKey<String> =
AttributeKey.stringKey({{ attribute.name | screaming_snake_case }})
{%- elif attribute.type == "boolean" %}
val {{ attribute.name | screaming_snake_case }}_KEY: AttributeKey<Boolean> =
AttributeKey.booleanKey({{ attribute.name | screaming_snake_case }})
{%- elif attribute.type == "int" %}
val {{ attribute.name | screaming_snake_case }}_KEY: AttributeKey<Long> =
AttributeKey.longKey({{ attribute.name | screaming_snake_case }})
{%- elif attribute.type == "double" %}
val {{ attribute.name | screaming_snake_case }}_KEY: AttributeKey<Double> =
AttributeKey.doubleKey({{ attribute.name | screaming_snake_case }})
val {{ attribute.name | screaming_snake_case }}_KEY: AttributeKey<{{ itype | map_text("kotlin_key_generic") }}> =
AttributeKey.{{ itype | map_text("kotlin_key_factory") }}({{ attribute.name | screaming_snake_case }})
{%- endif %}
{%- endif %}
{%- endfor %}
{%- for attribute in ctx.attributes | rejectattr("name", "in", ctx.excluded_attributes) %}
{%- if attribute is enum %}

{{ ("Values for " ~ (attribute.name | screaming_snake_case) ~ ".") | comment | trim | indent(4) -}}
{%- if attribute is deprecated %}
@Deprecated("{{ attribute.deprecated.note | replace('\n', ' ') | trim }}")
{%- endif %}
enum class {{ attribute.name | pascal_case }}Values(
val value: {{ attribute.type | instantiated_type | map_text("kotlin_enum_type") }},
) {
{%- for member in attribute.type.members %}
{{ "\n" if not loop.first }} {{ [member.brief or (member.id ~ '.')] | comment | trim | indent(8) }}
{{ member.id | screaming_snake_case }}({{ member.value | print_member_value }}),
{%- endfor %}
}
{%- endif %}
{%- endfor %}
}
22 changes: 21 additions & 1 deletion semconv/templates/registry/kotlin/weaver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,34 @@ templates:
brief: .brief,
note: .note,
deprecated: .deprecated,
attributes: ((.attributes // []) | unique_by(.name))
attributes: ((.attributes // [])
| map(select(.type != "any"))
| unique_by(.name))
})
application_mode: each
file_name: "io/opentelemetry/android/semconv/events/{{ctx.name | pascal_case}}Event.kt"
text_maps:
kotlin_enum_type:
int: Long
string: String
kotlin_key_generic:
string: String
boolean: Boolean
int: Long
double: Double
"string[]": List<String>
"boolean[]": List<Boolean>
"int[]": List<Long>
"double[]": List<Double>
kotlin_key_factory:
string: stringKey
boolean: booleanKey
int: longKey
double: doubleKey
"string[]": stringArrayKey
"boolean[]": booleanArrayKey
"int[]": longArrayKey
"double[]": doubleArrayKey
kotlin_event_type:
int: Long
double: Double
Expand Down