Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drop-in replacement for elastic Node distribution #17

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e6b6433
Added Elastic config files and Elastic-specific readme
AlexanderWert Apr 11, 2023
b7e1781
fix paths to images
graphaelli Apr 18, 2023
4ac78b0
Revert "fix paths to images in README"
graphaelli Apr 26, 2023
7c04ec4
Update README.md
amitkanfer Apr 18, 2023
374af14
Added Teletrace forked opentelemetry demo repo to Readme (#837)
haimrait Apr 13, 2023
069735e
Added clarification on the endpoint config requiring to contain the port
AlexanderWert Jul 24, 2023
d0a7f68
fixes otelcol-config-extras.yml with upstream changes
AlexanderWert Aug 3, 2023
59a1954
disabled compression on elastic otlp exporter
AlexanderWert Oct 4, 2023
e9143e3
Create merge-upstream.yaml
AlexanderWert Oct 27, 2023
f72f4e8
Update README.md to include helm repo update
AlexanderWert Nov 14, 2023
e255b89
Use specific token with workflow permissions
ChrsMark Nov 29, 2023
20c895e
Change structure and use new secret
ChrsMark Nov 29, 2023
cbed314
Switch back to otel token
ChrsMark Nov 29, 2023
2d263ce
Adds example configuration in values.yaml for k8s monitoring
ChrsMark Nov 23, 2023
02fc0c8
Add autodiscovery example
ChrsMark Nov 27, 2023
207727d
Update the doc README
ChrsMark Nov 27, 2023
8ec9c34
Merge cluster level metrics with demo and add additional daemonset
ChrsMark Nov 28, 2023
bd61780
Comment out autodiscovery part
ChrsMark Nov 29, 2023
bec1945
Add health_check extension
ChrsMark Nov 29, 2023
81f0ea1
Remove invalid `filter` processor
sorenlouv Apr 26, 2024
2e8b8f2
drop-in replacement for elastic Node distribution
rogercoll Jun 3, 2024
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
71 changes: 71 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!-- markdownlint-disable-next-line -->
# <img src="https://opentelemetry.io/img/logos/opentelemetry-logo-nav.png" alt="OTel logo" width="32"> :heavy_plus_sign: <img src="https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt601c406b0b5af740/620577381692951393fdf8d6/elastic-logo-cluster.svg" alt="OTel logo" width="32"> OpenTelemetry Demo with Elastic Observability

The following guide describes how to setup the OpenTelemetry demo with Elastic Observability using [Docker compose](#docker-compose) or [Kubernetes](#kubernetes).

## Docker compose

1. Start a free trial on [Elastic Cloud](https://cloud.elastic.co/) and copy the `endpoint` and `secretToken` from the Elastic APM setup instructions in your Kibana.
1. Open the file `src/otelcollector/otelcol-config-extras.yml` in an editor and replace the following two placeholders:
- `YOUR_APM_ENDPOINT_WITHOUT_HTTPS_PREFIX`: your Elastic APM endpoint (*without* `https://` prefix) that *must* also include the port (example: `1234567.apm.us-west2.gcp.elastic-cloud.com:443`).
- `YOUR_APM_SECRET_TOKEN`: your Elastic APM secret token.
1. Start the demo with the following command from the repository's root directory:
```
docker-compose up -d
```

## Kubernetes
### Prerequisites:
- Create a Kubernetes cluster. There are no specific requirements, so you can create a local one, or use a managed Kubernetes cluster, such as [GKE](https://cloud.google.com/kubernetes-engine), [EKS](https://aws.amazon.com/eks/), or [AKS](https://azure.microsoft.com/en-us/products/kubernetes-service).
- Set up [kubectl](https://kubernetes.io/docs/reference/kubectl/).
- Set up [Helm](https://helm.sh/).

### Start the Demo
1. Setup Elastic Observability on Elastic Cloud.
1. Create a secret in Kubernetes with the following command.
```
kubectl create secret generic elastic-secret \
--from-literal=elastic_apm_endpoint='YOUR_APM_ENDPOINT_WITHOUT_HTTPS_PREFIX' \
--from-literal=elastic_apm_secret_token='YOUR_APM_SECRET_TOKEN'
```
Don't forget to replace
- `YOUR_APM_ENDPOINT_WITHOUT_HTTPS_PREFIX`: your Elastic APM endpoint (*without* `https://` prefix) that *must* also include the port (example: `1234567.apm.us-west2.gcp.elastic-cloud.com:443`).
- `YOUR_APM_SECRET_TOKEN`: your Elastic APM secret token
1. Execute the following commands to deploy the OpenTelemetry demo to your Kubernetes cluster:
```
# switch to the kubernetes/elastic-helm directory
cd kubernetes/elastic-helm

# !(when running it for the first time) add the open-telemetry Helm repostiroy
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts

# !(when an older helm open-telemetry repo exists) update the open-telemetry helm repo
helm repo update open-telemetry

# deploy the demo through helm install
helm install -f values.yaml my-otel-demo open-telemetry/opentelemetry-demo
```

#### Kubernetes monitoring

This demo already enables cluster level metrics collection with `clusterMetrics` and
Kubernetes events collection with `kubernetesEvents`.

In order to add Node level metrics collection and autodiscovery for Redis Pods
we can run an additional Otel collector Daemonset with the following:

`helm install daemonset open-telemetry/opentelemetry-collector --values daemonset.yaml`

## Explore and analyze the data With Elastic

### Service map
![Service map](service-map.png "Service map")

### Traces
![Traces](trace.png "Traces")

### Correlation
![Correlation](correlation.png "Correlation")

### Logs
![Logs](logs.png "Logs")
Binary file added .github/correlation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/logs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/service-map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/trace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions .github/workflows/merge-upstream.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Scheduled Merge Upstream
on:
workflow_dispatch:
schedule:
- cron: '23 0/3 * * *'

jobs:
merge_upstream:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: main
fetch-depth: 0
token: ${{ secrets.OTEL_DEMO_MERGE_SECRET }}
- name: fetch and push
env:
GITHUB_TOKEN: ${{ github.token }}
UPSTREAM: https://github.com/open-telemetry/opentelemetry-demo
run: |
git config --global user.name "github-actions"
git config --global user.email "[email protected]"

git remote add upstream "${UPSTREAM}"

# Get all recent branches and commits from the upstream
git fetch upstream main

git rebase upstream/main

if [ "$(git status | grep diverged)" ]; then
git push origin $(git branch --show-current) --force;
fi;
notify-failure:
needs: [merge_upstream]
if: always() && needs.merge_upstream.result != 'success'
runs-on: ubuntu-latest
steps:
- name: Get previous workflow status
uses: Mercymeilya/[email protected]
id: last_status
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Slack notification
if: success() && steps.last_status.outputs.last_status == 'success'
env:
SLACK_WEBHOOK: ${{ secrets.OTELSLACKCHANNELWEBHOOK }}
SLACK_UNFURL_LINKS: "true"
uses: AlexanderWert/[email protected]
with:
args: |
:wave:
Auto-merge of the <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|elastic/opentelemetry-demo> repository with the upstream failed!
Manual resolution of the merge conflicts is required!

56 changes: 56 additions & 0 deletions kubernetes/elastic-helm/daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
mode: daemonset
presets:
logsCollection:
enabled: true
hostMetrics:
enabled: true
kubeletMetrics:
enabled: true
kubernetesAttributes:
enabled: true

extraEnvs:
- name: ELASTIC_APM_ENDPOINT
valueFrom:
secretKeyRef:
name: elastic-secret
key: elastic_apm_endpoint
- name: ELASTIC_APM_SECRET_TOKEN
valueFrom:
secretKeyRef:
name: elastic-secret
key: elastic_apm_secret_token

config:
extensions:
k8s_observer:
auth_type: serviceAccount
node: ${env:K8S_NODE_NAME}
observe_pods: true
exporters:
otlp/elastic:
endpoint: ${ELASTIC_APM_ENDPOINT}
compression: none
headers:
Authorization: Bearer ${ELASTIC_APM_SECRET_TOKEN}
receivers:
receiver_creator:
watch_observers: [ k8s_observer ]
receivers:
redis:
rule: type == "port" && pod.name matches "redis"
config:
collection_interval: 2s
service:
extensions: [health_check, k8s_observer]
pipelines:
traces:
processors: [batch]
exporters: [otlp/elastic]
metrics:
receivers: [ receiver_creator]
processors: [batch]
exporters: [otlp/elastic]
logs:
processors: [batch]
exporters: [otlp/elastic]
61 changes: 61 additions & 0 deletions kubernetes/elastic-helm/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
opentelemetry-collector:
mode: "deployment"
presets:
kubernetesAttributes:
enabled: true
kubernetesEvents:
enabled: true
clusterMetrics:
enabled: true

extraEnvs:
- name: ELASTIC_APM_ENDPOINT
valueFrom:
secretKeyRef:
name: elastic-secret
key: elastic_apm_endpoint
- name: ELASTIC_APM_SECRET_TOKEN
valueFrom:
secretKeyRef:
name: elastic-secret
key: elastic_apm_secret_token
config:
exporters:
otlp/elastic:
endpoint: ${ELASTIC_APM_ENDPOINT}
compression: none
headers:
Authorization: Bearer ${ELASTIC_APM_SECRET_TOKEN}
receivers:
otlp:
protocols:
grpc:
endpoint: ${MY_POD_IP}:4317
http:
cors:
allowed_origins:
- http://*
- https://*
endpoint: ${MY_POD_IP}:4318
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/elastic]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp/elastic]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp/elastic]
grafana:
enabled: false

jaeger:
enabled: false

prometheus:
enabled: false
23 changes: 23 additions & 0 deletions src/otelcollector/otelcol-config-extras.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,26 @@
# pipelines:
# traces:
# exporters: [spanmetrics, otlphttp/example]

exporters:
otlp/elastic:
# !!! Elastic APM https endpoint WITHOUT the "https://" prefix
endpoint: "YOUR_APM_ENDPOINT_WITHOUT_HTTPS_PREFIX"
compression: none
headers:
Authorization: "Bearer YOUR_APM_SECRET_TOKEN"

service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [spanmetrics, otlp/elastic]
metrics:
receivers: [otlp, spanmetrics]
processors: [batch]
exporters: [otlp/elastic]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp/elastic]
4 changes: 2 additions & 2 deletions src/paymentservice/opentelemetry.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

const opentelemetry = require("@opentelemetry/sdk-node")
const {ElasticNodeSDK} = require("@elastic/opentelemetry-node/sdk")
const {getNodeAutoInstrumentations} = require("@opentelemetry/auto-instrumentations-node")
const {OTLPTraceExporter} = require('@opentelemetry/exporter-trace-otlp-grpc')
const {OTLPMetricExporter} = require('@opentelemetry/exporter-metrics-otlp-grpc')
Expand All @@ -12,7 +12,7 @@ const {containerDetector} = require('@opentelemetry/resource-detector-container'
const {gcpDetector} = require('@opentelemetry/resource-detector-gcp')
const {envDetector, hostDetector, osDetector, processDetector} = require('@opentelemetry/resources')

const sdk = new opentelemetry.NodeSDK({
const sdk = new ElasticNodeSDK({
traceExporter: new OTLPTraceExporter(),
instrumentations: [
getNodeAutoInstrumentations({
Expand Down
Loading
Loading