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

chore: add Otel and Uptrace example #37

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/stubs
/vendor
vendor
composer.lock
45 changes: 45 additions & 0 deletions example/opentelemetry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Example for Relay OpenTelemetry instrumentation

This example demonstrates how to monitor Redis using [OpenTelemetry](https://opentelemetry.io/) and
[Uptrace](https://uptrace.dev/get/open-source-apm.html. It requires Docker to start Redis Server and Uptrace.

**Step 1**. Download the example using Git:

```shell
git clone https://github.com/cachewerk/relay.git
cd example/opentelemetry
```

**Step 2**. Start the services using Docker:

```shell
docker-compose up -d
```

**Step 3**. Make sure Redis and Uptrace are running:

```shell
docker-compose logs redis
docker-compose logs uptrace
```

**Step 4**. Install dependencies and run the Relay example:

```shell
composer install
php main.php
```

**Step 5**. Follow the link from the CLI to view the trace:

```shell
php main.php
trace: http://localhost:14318/traces/ee029d8782242c8ed38b16d961093b35
```

![Relay trace](./image/relay-trace.png)

You can also open Uptrace UI at [http://localhost:14318](http://localhost:14318) to view available
spans, logs, and metrics.

See [Monitoring Relay Redis client with OpenTelemetry](https://uptrace.dev/blog/posts/relay-cache-opentelemetry.html).
19 changes: 19 additions & 0 deletions example/opentelemetry/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "relay/example-opentelemetry",
"authors": [
{
"name": "Vladimir Mihailenco",
"email": "[email protected]"
}
],
"require": {
"cachewerk/relay": "^0.5.1",
"uptrace/uptrace": "0.1.2"
},
"autoload": {
"psr-4": {
"CacheWerk\\Relay\\": "../../src/"
}
},
"minimum-stability": "dev"
}
53 changes: 53 additions & 0 deletions example/opentelemetry/config/alertmanager.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# See https://prometheus.io/docs/alerting/latest/configuration/ for details.

global:
# The smarthost and SMTP sender used for mail notifications.
smtp_smarthost: "mailhog:1025"
smtp_from: "[email protected]"
smtp_require_tls: false

receivers:
- name: "team-X"
email_configs:
- to: "[email protected]"
send_resolved: true

# The root route on which each incoming alert enters.
route:
# The labels by which incoming alerts are grouped together. For example,
# multiple alerts coming in for cluster=A and alertname=LatencyHigh would
# be batched into a single group.
group_by: ["alertname", "cluster", "service"]

# When a new group of alerts is created by an incoming alert, wait at
# least 'group_wait' to send the initial notification.
# This way ensures that you get multiple alerts for the same group that start
# firing shortly after another are batched together on the first
# notification.
group_wait: 30s

# When the first notification was sent, wait 'group_interval' to send a batch
# of new alerts that started firing for that group.
group_interval: 5m

# If an alert has successfully been sent, wait 'repeat_interval' to
# resend them.
repeat_interval: 3h

# A default receiver
receiver: team-X

# All the above attributes are inherited by all child routes and can
# overwritten on each.

# The child route trees.
routes:
# This route matches error alerts created from spans or logs.
- matchers:
- alert_kind="error"
group_interval: 24h
receiver: team-X

# The directory from which notification templates are read.
templates:
- "/etc/alertmanager/template/*.tmpl"
68 changes: 68 additions & 0 deletions example/opentelemetry/config/otel-collector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
extensions:
health_check:
pprof:
endpoint: 0.0.0.0:1777
zpages:
endpoint: 0.0.0.0:55679

receivers:
otlp:
protocols:
grpc:
http:
hostmetrics:
collection_interval: 10s
scrapers:
cpu:
disk:
load:
filesystem:
memory:
network:
paging:
redis:
endpoint: "redis-server:6379"
collection_interval: 10s
jaeger:
protocols:
grpc:

processors:
resourcedetection:
detectors: ["system"]
batch:
send_batch_size: 10000
timeout: 10s

exporters:
logging:
logLevel: debug
otlp:
endpoint: uptrace:14317
tls:
insecure: true
headers: { "uptrace-dsn": "http://project2_secret_token@localhost:14317/2" }

service:
# telemetry:
# logs:
# level: DEBUG
pipelines:
traces:
receivers: [otlp, jaeger]
processors: [batch]
exporters: [otlp, logging]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics/hostmetrics:
receivers: [hostmetrics, redis]
processors: [batch, resourcedetection]
exporters: [otlp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp]

extensions: [health_check, pprof, zpages]
39 changes: 39 additions & 0 deletions example/opentelemetry/config/vector.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[sources.syslog_logs]
type = "demo_logs"
format = "syslog"
interval = 0.1

[sources.apache_common_logs]
type = "demo_logs"
format = "apache_common"
interval = 0.1

[sources.apache_error_logs]
type = "demo_logs"
format = "apache_error"
interval = 0.1

[sources.json_logs]
type = "demo_logs"
format = "json"
interval = 0.1

# Parse Syslog logs
# See the Vector Remap Language reference for more info: https://vrl.dev
[transforms.parse_logs]
type = "remap"
inputs = ["syslog_logs"]
source = '''
. = parse_syslog!(string!(.message))
'''

# Export data to Uptrace.
[sinks.uptrace]
type = "http"
inputs = ["parse_logs", "apache_common_logs", "apache_error_logs", "json_logs"]
encoding.codec = "json"
framing.method = "newline_delimited"
compression = "gzip"
uri = "http://uptrace:14318/api/v1/vector/logs"
#uri = "https://api.uptrace.dev/api/v1/vector/logs"
headers.uptrace-dsn = "http://project2_secret_token@localhost:14317/2"
81 changes: 81 additions & 0 deletions example/opentelemetry/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
version: "3"

services:
clickhouse:
image: clickhouse/clickhouse-server:22.10
restart: on-failure
environment:
CLICKHOUSE_DB: uptrace
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "localhost:8123/ping"]
interval: 1s
timeout: 1s
retries: 30
volumes:
- ch_data:/var/lib/clickhouse
ports:
- "8123:8123"
- "9000:9000"

uptrace:
image: "uptrace/uptrace:1.2.4"
#image: "uptrace/uptrace-dev:latest"
restart: on-failure
volumes:
- uptrace_data:/var/lib/uptrace
- ./uptrace.yml:/etc/uptrace/uptrace.yml
#environment:
# - DEBUG=2
ports:
- "14317:14317"
- "14318:14318"
depends_on:
clickhouse:
condition: service_healthy

otel-collector:
image: otel/opentelemetry-collector-contrib:0.59.0
restart: on-failure
volumes:
- ./config/otel-collector.yaml:/etc/otelcol-contrib/config.yaml
ports:
- "4317:4317"
- "4318:4318"

redis-server:
image: redis
ports:
- "6379:6379"
redis-cli:
image: redis

vector:
image: timberio/vector:0.24.X-alpine
volumes:
- ./config/vector.toml:/etc/vector/vector.toml:ro

alertmanager:
image: prom/alertmanager:v0.24.0
restart: on-failure
volumes:
- ./config/alertmanager.yml:/etc/alertmanager/config.yml
- alertmanager_data:/alertmanager
ports:
- 9093:9093
command:
- "--config.file=/etc/alertmanager/config.yml"
- "--storage.path=/alertmanager"

mailhog:
image: mailhog/mailhog:v1.0.1
restart: on-failure
ports:
- "8025:8025"

volumes:
uptrace_data:
driver: local
ch_data:
driver: local
alertmanager_data:
driver: local
Binary file added example/opentelemetry/image/metrics.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 example/opentelemetry/image/relay-trace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions example/opentelemetry/main.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';

use \CacheWerk\Relay\Psr\Tracing\RelayOpenTelemetry;

$conf = new Uptrace\Config();
$conf->setDsn('http://project2_secret_token@localhost:14318/2');
$conf->setServiceName('myservice');
$conf->setServiceVersion('1.0.0');

$uptrace = new Uptrace\Distro($conf);
$tracerProvider = $uptrace->createTracerProvider();
$tracer = $tracerProvider->getTracer('relay/example-opentelemetry');

$redis = new RelayOpenTelemetry(function() {
return new Relay\Relay;
}, $tracerProvider);

$redis->connect('127.0.0.1', 6379);

$span = handleRequest($tracer, $redis);
echo $uptrace->traceUrl($span) . PHP_EOL;

for ($i = 0; $i <= 1000000; $i++) {
handleRequest($tracer, $redis);
sleep(1);
}

// Send buffered spans and free resources.
$tracerProvider->shutdown();

function handleRequest($tracer, $redis) {
$span = $tracer->spanBuilder('handle-request')->startSpan();
$spanScope = $span->activate();

$value = $redis->get('count');
$redis->set('counter', (int)$value + 1);

$redis->multi()
->set('key1', 'val1')
->get('key1')
->set('key2', 'val2')
->get('key2')
->exec();

$pipe = $redis->pipeline();
for ($i = 0; $i <= 100; $i++) {
$pipe->set('key' . $i, '');
}
$pipe->exec();

$it = NULL;
do {
// Scan for some keys
$arr_keys = $redis->scan($it);
} while ($it > 0);

$spanScope->detach();
$span->end();

return $span;
}
Loading