Skip to content
Draft
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ This is the default kind in both development and production.

Exports traces and metrics to Dynatrace.
Hence, a Dynatrace instance is required and the app must be bound to that Dynatrace instance.
Please note, that for the binding to be resolved, the bound service instance needs to use the tag `dynatrace`, regardless of whether it is a user-provided service instance or not.

Use via `cds.requires.telemetry.kind = 'to-dynatrace'`.

Expand Down Expand Up @@ -289,7 +290,13 @@ In order to receive OpenTelemetry credentials in the binding to the SAP Cloud Lo
}
```

If you are binding your app to SAP Cloud Logging via a [user-provided service instance](https://docs.cloudfoundry.org/devguide/services/user-provided.html), make sure that it has either tag `cloud-logging` or `Cloud Logging`.
If you are binding your app to SAP Cloud Logging via a [user-provided service instance](https://docs.cloudfoundry.org/devguide/services/user-provided.html), make sure that it has the tag `Cloud Logging`.

> Tip: To add the required tag to an existing user-provided service, you can use:
> ```
> cf update-user-provided-service {service-name} -t "Cloud Logging"
> ```
> For detailed information about binding resolution in CAP, consult [the relevant documentation](https://cap.cloud.sap/docs/node.js/cds-connect#vcap_services).

### `telemetry-to-jaeger`

Expand Down
2 changes: 1 addition & 1 deletion lib/logging/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function _getExporter() {

if (kind.match(/to-cloud-logging$/)) {
if (!credentials) credentials = getCredsForCLSAsUPS()
if (!credentials) throw new Error('No SAP Cloud Logging credentials found.')
if (!credentials) throw new Error('No SAP Cloud Logging credentials found. Make sure the bound service instance uses the tag "Cloud Logging".')
augmentCLCreds(credentials)
config.url ??= credentials.url
config.credentials ??= credentials.credentials
Expand Down
4 changes: 2 additions & 2 deletions lib/metrics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function _getExporter() {

if (kind.match(/to-dynatrace$/)) {
if (!credentials) credentials = getCredsForDTAsUPS()
if (!credentials) throw new Error('No Dynatrace credentials found.')
if (!credentials) throw new Error('No Dynatrace credentials found. Make sure the bound service instance uses the tag "dynatrace".')
config.url ??= `${credentials.apiurl}/v2/otlp/v1/metrics`
config.headers ??= {}
// credentials.rest_apitoken?.token is deprecated and only supported for compatibility reasons
Expand All @@ -64,7 +64,7 @@ function _getExporter() {

if (kind.match(/to-cloud-logging$/)) {
if (!credentials) credentials = getCredsForCLSAsUPS()
if (!credentials) throw new Error('No SAP Cloud Logging credentials found.')
if (!credentials) throw new Error('No SAP Cloud Logging credentials found. Make sure the bound service instance uses the tag "Cloud Logging".')
augmentCLCreds(credentials)
config.url ??= credentials.url
config.credentials ??= credentials.credentials
Expand Down
4 changes: 2 additions & 2 deletions lib/tracing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function _getExporter() {

if (kind.match(/to-dynatrace$/)) {
if (!credentials) credentials = getCredsForDTAsUPS()
if (!credentials) throw new Error('No Dynatrace credentials found')
if (!credentials) throw new Error('No Dynatrace credentials found. Make sure the bound service instance uses the tag "dynatrace".')
config.url ??= `${credentials.apiurl}/v2/otlp/v1/traces`
config.headers ??= {}
// credentials.rest_apitoken?.token is deprecated and only supported for compatibility reasons
Expand All @@ -119,7 +119,7 @@ function _getExporter() {

if (kind.match(/to-cloud-logging$/)) {
if (!credentials) credentials = getCredsForCLSAsUPS()
if (!credentials) throw new Error('No SAP Cloud Logging credentials found')
if (!credentials) throw new Error('No SAP Cloud Logging credentials found. Make sure the bound service instance uses the tag "Cloud Logging".')
augmentCLCreds(credentials)
config.url ??= credentials.url
config.credentials ??= credentials.credentials
Expand Down
15 changes: 11 additions & 4 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ function getCredsForDTAsUPS() {
if (!process.env.VCAP_SERVICES) return
const vcap = JSON.parse(process.env.VCAP_SERVICES)

// to support connection via user-provided services, APMs requirement is that the instance name contains "dynatrace"
// Legacy Compat:
// > APMs requirement is that the instance name contains "dynatrace"
// > In addition to matching predicate defined in package.json, also support
// > - name matching /dynatrace/
// ... in case binding info is available from environment variable VCAP_SERVICES
const dt = vcap['user-provided']?.find(b => b.name.match(/dynatrace/))
if (dt) return dt.credentials
}
Expand All @@ -116,15 +120,18 @@ function getCredsForCLSAsUPS() {
const vcap = JSON.parse(process.env.VCAP_SERVICES)
let ups

// to support connection via user-provided services, the instance must have either tag "cloud-logging" or "Cloud Logging"
// Legacy Compat:
// > In addition to matching predicate defined in package.json, also support
// > - tag: "cloud-logging"
// > - name matching /cloud-logging/
// ... in case binding info is available from environment variable VCAP_SERVICES
ups = vcap['user-provided']?.find(e => e.tags.includes('cloud-logging') || e.tags.includes('Cloud Logging'))
if (ups) return ups.credentials

// legacy compat
ups = vcap['user-provided']?.find(b => b.name.match(/cloud-logging/))
if (ups) {
// prettier-ignore
LOG._warn && LOG.warn('User-provided service instances of SAP Cloud Logging should have either tag "cloud-logging" or "Cloud Logging"')
LOG._warn && LOG.warn('User-provided service instances of SAP Cloud Logging should have the tag "Cloud Logging"')
return ups.credentials
}
}
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@
}
},
"telemetry-to-dynatrace": {
"vcap": {
"label": "dynatrace"
},
"vcap": [
{ "label": "dynatrace" },
{ "tag": "dynatrace" }
],
"tracing": {
"exporter": {
"module": "@opentelemetry/exporter-trace-otlp-proto",
Expand All @@ -124,9 +125,10 @@
"token_name": "ingest_apitoken"
},
"telemetry-to-cloud-logging": {
"vcap": {
"label": "cloud-logging"
},
"vcap": [
{ "label": "cloud-logging" },
{ "tag": "Cloud Logging" }
],
"tracing": {
"exporter": {
"module": "@opentelemetry/exporter-trace-otlp-grpc",
Expand Down