You can send the same daily aggregate user activity metrics to your OpenTelemetry-compatible collector. Kiro pushes credits, overage credits, messages, conversations, and per-model message counts once a day at 02:00 UTC. The export is configured by an administrator and can't be configured by individual users.
Kiro supports OTLP/gRPC and OTLP/HTTP with protobuf encoding. gRPC is the default. In the Kiro console, the HTTP option is labeled HTTP/protobuf.
The OpenTelemetry export and the CSV report in Amazon S3 are independent. You can enable either format or both. Kiro stores only the ARN of your AWS Secrets Manager secret and reads the collector endpoint and authentication header from the secret at export time.
Choose the protocol, endpoint, and single authentication header that your destination accepts before you create the secret. Use the following destination configurations:
| Destination | Protocol | Endpoint | Authentication header |
|---|---|---|---|
| Honeycomb | gRPC | https://api.honeycomb.io:443 | X-Honeycomb-Team=ingest-key |
| Elastic | gRPC | https://deployment.ingest.region.gcp.elastic-cloud.com:443 | Authorization=ApiKey base64-credential |
| OpenSearch through an OTLP receiver such as Data Prepper | gRPC | https://collector-host:21891 | Authorization=Basic credential |
| Self-hosted OTLP collector | gRPC or HTTP/protobuf | https://collector-host:port | Authentication header required by your collector |
| Datadog | HTTP/protobuf | https://otlp.datadoghq.com/v1/metrics | dd-api-key=api-key |
| Amazon CloudWatch | HTTP/protobuf | https://monitoring.region.amazonaws.com/v1/metrics | Authorization=Bearer api-key |
| Dynatrace | HTTP/protobuf | https://environment.live.dynatrace.com/api/v2/otlp | Authorization=Api-Token access-token |
Replace deployment, region, collector-host, and environment with values from your destination. Replace the credential placeholder in the header with your ingestion credential.
Use an ingestion credential rather than an administrative credential. For Honeycomb, use the combined ingest key ID and secret, not the key ID alone. For Elastic, base64-encode id:api_key. For Datadog, use an API key, not an application key. For Dynatrace, use an access token with metrics.ingest permission. Amazon CloudWatch requires a bearer API key because Kiro can't sign the export with AWS Signature Version 4 (SigV4). To create the key, see Setting up bearer token authentication for Metrics in the Amazon CloudWatch User Guide.
Create a symmetric customer managed AWS KMS key for encryption and decryption. The default aws/secretsmanager key can't be used because Kiro reads the secret from another AWS account. The KMS key, Secrets Manager secret, and Kiro profile must be in the same AWS Region.
Add the following statement to the KMS key policy. Replace region with the Region of your Kiro profile. This grants the q.amazonaws.com service principal permission to decrypt the secret through Secrets Manager in that Region.
{ "Sid": "AllowKiroDecryptViaSecretsManager", "Effect": "Allow", "Principal": { "Service": "q.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:DescribeKey" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "secretsmanager.region.amazonaws.com" } } }
Save the policy. You select this key as the encryption key when you create the secret.
In the same Region as your Kiro profile, create an Other type of secret in AWS Secrets Manager. On the Plaintext tab, enter a JSON object with exactly these keys:
{ "OTEL_EXPORTER_OTLP_ENDPOINT": "https://collector-host:443", "OTEL_EXPORTER_OTLP_HEADERS": "Header-Name=token" }
OTEL_EXPORTER_OTLP_ENDPOINT is your collector's OTLP endpoint.OTEL_EXPORTER_OTLP_HEADERS is one authentication header in Name=value format. Kiro splits the string on the first =, so base64 padding such as == in the value is preserved.Your collector endpoint must be reachable from the public internet and use a publicly trusted TLS certificate. Kiro rejects self-signed certificates. Use a hostname rather than an IP address because Kiro verifies the certificate hostname.
For Encryption key, select the customer managed KMS key that you created. Don't select aws/secretsmanager. Add the following resource policy to the secret so Kiro can read its value:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowKiroGetSecretValue", "Effect": "Allow", "Principal": { "Service": "q.amazonaws.com" }, "Action": "secretsmanager:GetSecretValue", "Resource": "*" } ] }
Store the secret and copy its secret ARN, which has the format arn:aws:secretsmanager:region:accountId:secret:secretName-randomSuffix.
Sign in to the AWS console.
Switch to the Kiro console. You must have the permissions in Policy: Allow administrators to configure Kiro and subscribe users.
Choose Settings.
Under Kiro user activity reports, choose Edit.
Choose the OpenTelemetry (OTel) export format.
Enter the Secrets Manager secret ARN.
Select the protocol that your collector accepts: gRPC or HTTP/protobuf.
Choose Enable.
The first export runs during the next 02:00 UTC cycle. Metrics for an activity date are sent the following day, and Kiro doesn't send data to your collector when you save the configuration.
Kiro doesn't send success or failure notifications. Confirm delivery in your destination by querying kiro.daily.credits or another exported metric and filtering on the resource attribute service.name = kiro-enterprise.
A successful export has these characteristics:
kiro.daily.credits and kiro.daily.messages are present.kiro.daily.model_messages has one datapoint per model.date attribute identifies the activity date, which is the day before the export ran.kiro.user.id, kiro.client.type, and kiro.user.new.Prometheus-based backends can replace periods in metric names with underscores. For example, kiro.daily.credits can appear as kiro_daily_credits.
Check the destination because Kiro treats a request accepted by the collector as successful even if the collector later rejects its datapoints.
| Destination | Where to verify |
|---|---|
| Honeycomb | Open the kiro-enterprise dataset and visualize SUM(kiro.daily.credits). |
| Elastic | In Kibana, use Discover or Metrics Explorer and filter on service.name : "kiro-enterprise". |
| OpenSearch | Query the configured index for serviceName:kiro-enterprise. For example: curl -u user:password "https://opensearch-host:9200/index-prefix-*/_search?q=serviceName:kiro-enterprise&pretty". |
| Datadog | In Metrics Explorer, open kiro.daily.credits and filter on the service tag. |
| Amazon CloudWatch | Run a PromQL range query against https://monitoring.region.amazonaws.com/api/v1/query_range. Metrics don't appear in the classic metrics console or through ListMetrics. |
| Dynatrace | In Notebooks, run a DQL query such as timeseries mm = sum(kiro.daily.model_messages), by:{kiro.model.name}, from: -2h. |
Each resulting time series receives one daily datapoint. If a range query returns no data, use a narrow window around the export time and a fine step, such as 60 seconds. A metric name can remain in an index or autocomplete after its datapoints fall outside the selected time window, so confirm that the query returns datapoints rather than only a metric name.
All exported metrics are monotonic OTLP Sum counters in the kiro.daily.* namespace.
| Metric | Description | Corresponding CSV column |
|---|---|---|
kiro.daily.credits | Credits used | Credits_Used |
kiro.daily.overage_credits | Overage credits used | Overage_Credits_Used |
kiro.daily.messages | Total messages | Total_Messages |
kiro.daily.conversations | Chat conversations | Chat_Conversations |
kiro.daily.model_messages | Messages per model | *model_name*_messages |
Each kiro.daily.model_messages datapoint includes kiro.model.name, which identifies the model represented by the corresponding dynamic CSV column.
Each datapoint can include the following attributes:
| Attribute | Type | Presence | Description |
|---|---|---|---|
kiro.user.id | string | Always | The user's IAM Identity Center user ID |
kiro.client.type | string | Always | Client type, such as KIRO_IDE, KIRO_CLI, or PLUGIN |
kiro.user.new | boolean | Always | Whether the user activated their subscription on the activity date |
date | string | When set | Activity date in UTC |
kiro.user.email | string | When resolvable | The user's email address; omitted if the directory lookup can't resolve it |
kiro.subscription.tier | string | When set | Subscription tier |
kiro.usage.limit | integer | When set | The user's usage limit |
kiro.overage.enabled | boolean | When set | Whether overage is enabled for the user |
kiro.overage.cap | double | When set | The user's overage cap, with the same decimal precision as the CSV report |
kiro.model.name | string | Only on kiro.daily.model_messages | Model name; hidden models are excluded |
Each export also includes these resource attributes:
| Resource attribute | Value | Description |
|---|---|---|
service.name | kiro-enterprise | Constant value for filtering Kiro metrics |
kiro.profile.arn | arn:aws:codewhisperer:region:accountId:profile/profileId | ARN of the Kiro profile that produced the metrics |
kiro.profile.id | Profile ID | ID of the Kiro profile |
kiro.account.id | AWS account ID | Account that contains the Kiro profile |
If no metrics arrive, verify that the secret and KMS key are in the Kiro profile's Region. Confirm that q.amazonaws.com has secretsmanager:GetSecretValue on the secret and kms:Decrypt and kms:DescribeKey on the KMS key. Then verify the protocol, endpoint reachability, TLS certificate, and authentication header required by your destination.
Export user activity with OpenTelemetry