OpenTelemetry Exporters
When you first turn on OpenTelemetry logging or metrics in CPK with no additional configuration, CPK will automatically configure default exporters for the logging and metrics pipelines. Read on to learn about the default exporters for logging and metrics, as well as how to configure exporters of your choosing.
Default Logging Exporter
Without explicit exporter configuration in place, the logs that are collected are sent to the Debug Exporter, which outputs the logs to the console. Since the collector is running in a sidecar container in a Kubernetes Pod, that console output is added to the container logs which you can retrieve with the kubectl logs
command. If you were running a logging-enabled PostgresCluster named hippo
in the postgres-operator
namespace and wanted to see your postgres
, patroni
, and pgbackrest
logs from the primary instance pod, the commands to retrieve those logs would look like this:
PG_CLUSTER_PRIMARY_POD=$(kubectl get pod -n postgres-operator -o name -l postgres-operator.crunchydata.com/cluster=hippo,postgres-operator.crunchydata.com/role=master)
kubectl -n postgres-operator logs "${PG_CLUSTER_PRIMARY_POD}" -c collector
However, this output is not the easiest to read and is not well organized or easily filtered or searched. You will therefore almost certainly want to export your logs to a dedicated backend or service of some kind where you can more easily search and read through your logs. Details on configuring exporters can be found in the Configuring OpenTelemetry Exporters section below.
Default Metrics Exporter
Without explicit exporter configuration in place, the metrics that are collected are sent to a Prometheus Exporter that is preconfigured to work seamlessly with our Monitoring stack. However, some users will want to use their own monitoring tools to visualize and analyze their metrics or might want to further transform the metrics data in some way.
Starting in CPK v5.8.3, you can now add exporters to your metrics pipelines to export the data as you set fit. Details on configuring exporters can be found in the Configuring OpenTelemetry Exporters section below.
Configuring OpenTelemetry Exporters
The OpenTelemetry Collector that we use has a plethora of exporters built into it that should satisfy most needs.
To use an exporter, you define it in the instrumentation.config.exporters
section. Fields in this section should follow the type[/name]
"component identifier" format where the type
is the exporter you want to use and name
is the optional name you want to give this configuration. The optional name allows you to define multiple configurations of the same exporter type. For example, you could have two configurations of the otlp
exporter where one is called otlp/logging
and the second is called otlp/metrics
. The value for each field is the configuration for that exporter. For example:
spec:
instrumentation:
config:
exporters:
otlp/logging:
endpoint: a-standalone-collector:4317
tls:
insecure: true
otlp/metrics:
endpoint: another-collector:4317
The configuration you define will differ depending on the exporter you are using. Please follow the documentation for your chosen exporter to determine what configuration to provide. OpenTelemetry keeps a list of exporters that are specific to the "contrib" collector, along with their documentation. There are also exporters available in the "contrib" collector that we use that have their documentation in the base collector repo.
Once the exporter is configured, you lastly need to tell the collector to use the exporter in the logging and/or metrics pipeline by adding the name of the exporter to the instrumentation.logs.exporters
and/or instrumentation.metrics.exporters
array, respectively. For example:
spec:
instrumentation:
config:
exporters:
otlp/logging:
endpoint: a-standalone-collector:4317
tls:
insecure: true
otlp/metrics:
endpoint: another-collector:4317
logs:
exporters: ['otlp/logging']
metrics:
exporters: ['otlp/metrics']
Note: Exporters can only be added to metrics pipelines in CPK v5.8.3 and higher.
You will find more examples of exporter configurations for commonly used logging and metrics backends in the Example Exporter Configurations section below.
Files
Some exporters might require that configuration be provided via files, such as separate config files, certificates, etc. This can be done via the instrumentation.config.files
section, which allows you to project files that are in Kubernetes Secrets, ConfigMaps, etc., into the volume that is mounted into the collector container. For example, creating a Secret with the following command:
kubectl -n postgres-operator create secret tls some-otel-exporter-certs --cert=server.crt --key=server.key
And then adding the following to your instrumentation spec:
spec:
instrumentation:
config:
files:
- secret:
name: some-otel-exporter-certs
Will result in the server.crt
and server.key
files being mounted in the /etc/otel-collector
directory of the collector container.
Environment Variables
Some exporters might also utilize environment variables for their configuration. You can add environment variables to the collector container by defining them in the instrumentation.config.environmentVariables
section. The value for any given variable can either be defined in plaintext in the manifest, or can be defined by referencing a ConfigMap or Secret. You can see the different value definition methods in the examples shown below.
One of the primary uses that we foresee for adding environment variables to the collector container is to give exporters the requisite information to authenticate to the backend services that receive the OTel data. For example, we might be using the googlecloud
and awss3
exporters to send our logging data to Google's monitoring service for analysis and to an AWS S3 bucket for safe keeping. Both of these exporters can use environment variables to retrieve the credentials and connection information needed to authenticate to their respective cloud services.
spec:
instrumentation:
config:
environmentVariables:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /etc/otel-collector/credentials/my-gcs-creds.json
- name: AWS_ACCESS_KEY_ID
valueFrom:
configMapKeyRef:
name: aws-credentials-configmap
key: access-key
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: aws-credentials-secret
key: secret-key
files:
- secret:
name: google-credentials-secret
items:
- key: my-gcs-creds.json
path: credentials/my-gcs-creds.json
As you can see, in this example the AWS specific environment variables are referencing values from a ConfigMap and a Secret, whereas the Google specific environment variable is referencing a credentials file that was mounted into the container using the instrumentation.config.files
section described earlier in our documentation.
Example Exporter Configurations
This section provides example configurations for a variety of different OpenTelemetry-compatible logging and metrics services and backends.
Google Cloud
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: otel-hippo
namespace: postgres-operator
spec:
instrumentation:
config:
detectors:
- name: gcp
exporters:
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/googlecloudexporter#configuration-reference
googlecloud:
log:
default_log_name: "collector-exported-log"
resource_filters:
- prefix: "k8s"
- prefix: "db"
logs:
exporters: ['googlecloud']
AWS Cloudwatch
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: otel-hippo
namespace: postgres-operator
spec:
instrumentation:
config:
environmentVariables:
- name: AWS_ACCESS_KEY_ID
valueFrom:
configMapKeyRef:
name: aws-credentials-configmap
key: access-key
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: aws-credentials-secret
key: secret-key
exporters:
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awscloudwatchlogsexporter
awscloudwatchlogs:
log_group_name: "otel-hippo-logs"
log_stream_name: "otel-hippo-logging-stream"
region: "us-east-1"
endpoint: "https://logs.us-east-1.api.aws"
logs:
exporters: ['awscloudwatchlogs']
Azure Monitor
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: otel-hippo
namespace: postgres-operator
spec:
instrumentation:
config:
environmentVariables:
- name: APPLICATIONINSIGHTS_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: azure-appinsights-secret
key: connection-string
exporters:
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/azuremonitorexporter
azuremonitor: {}
logs:
exporters: ['azuremonitor']
metrics:
exporters: ['azuremonitor']
OTLP
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: otel-hippo
namespace: postgres-operator
spec:
instrumentation:
config:
exporters:
# https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlpexporter#getting-started
otlp: # for exporting to another collector
endpoint: "otel-collector:4317"
tls:
insecure: true
logs:
exporters: ['otlp']