Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7a5da5a
chore: playground done
kirrg001 Apr 9, 2026
a046abc
chore: infra cor
kirrg001 Apr 9, 2026
378f117
chore: phase 1
abhilash-sivan May 4, 2026
c1ef77d
chore: phase 2
abhilash-sivan May 4, 2026
d261bc5
chore: phase 3
abhilash-sivan May 7, 2026
17710d0
chore: cleanup
abhilash-sivan May 7, 2026
0a6ec17
chore: rewrite
abhilash-sivan May 7, 2026
8a89eef
chore: test
abhilash-sivan May 7, 2026
c78331c
chore: a
abhilash-sivan May 7, 2026
bcb034e
chore: new fields
abhilash-sivan May 7, 2026
980a1c0
chore: test
abhilash-sivan May 7, 2026
5aebc15
test: fixed failing test
abhilash-sivan May 10, 2026
8c6cc88
chore: cleanup
abhilash-sivan May 10, 2026
c3179eb
chore: ui corrected
abhilash-sivan May 13, 2026
21c211d
chore: added kafka and pg, generalize
abhilash-sivan May 14, 2026
fcd7622
chore: update
abhilash-sivan May 14, 2026
c1253b0
chore: fix
abhilash-sivan May 15, 2026
d6c01a6
chore: clean
abhilash-sivan May 15, 2026
efd4103
chore: update
abhilash-sivan May 15, 2026
b85ae66
chore: added readme
abhilash-sivan May 18, 2026
b5a51c8
chore: added example
abhilash-sivan May 18, 2026
f79a641
chore: added example transformer
abhilash-sivan May 18, 2026
06835eb
chore: update readme to minimal
abhilash-sivan May 18, 2026
52be4b2
chore: update logic
abhilash-sivan May 19, 2026
b8a95a1
chore: spanBuffer uses temporary converter
abhilash-sivan May 19, 2026
402b4d3
chore: move files for using inside spanBuffer
abhilash-sivan May 19, 2026
3df77e8
chore: update
abhilash-sivan May 19, 2026
e8b37d9
chore: rearrange
abhilash-sivan May 19, 2026
059c844
chore: added separate transformer
abhilash-sivan May 20, 2026
c197345
chore: added example otel spans
abhilash-sivan May 20, 2026
0935eda
chore: make getSpanType dynamic
abhilash-sivan May 20, 2026
d805750
chore: fix status
abhilash-sivan May 20, 2026
0a099fd
chore: kafka systemName
abhilash-sivan May 20, 2026
3d4ae91
chore: v1 of multiple data key logic
abhilash-sivan May 21, 2026
90954b2
chore: refactor
abhilash-sivan May 21, 2026
d5575d7
chore: optimize additioanl attributes
abhilash-sivan May 22, 2026
4bdb790
chore: wip more dynamic
abhilash-sivan May 22, 2026
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 example-apps/collector/.env
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# All default settings defined here can be overridden by environment variables.

# MODE=npm
MODE=local
APP_PORT=2807
SENSOR_ENABLED=true
TRACING_ENABLED=true
Expand Down
3 changes: 3 additions & 0 deletions example-apps/collector/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ if (config.mode === 'npm') {
packageToRequire = '@instana/collector';
}

process.env.INSTANA_METRICS_TRANSMISSION_DELAY = 5000;
process.env.INSTANA_OTLP_FORMAT = 'true';

if (config.collectorEnabled) {
console.log(`enabling @instana/collector (requiring ${packageToRequire})`);
require(packageToRequire)({
Expand Down
4 changes: 4 additions & 0 deletions example-apps/otel-exporter-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
data.txt
npm-debug.log
.DS_Store
240 changes: 240 additions & 0 deletions example-apps/otel-exporter-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# OpenTelemetry Exporter Test App

A comprehensive Express.js application for testing OpenTelemetry tracing with Instana backend, including HTTP, PostgreSQL, and Kafka instrumentation.

## Features

- **HTTP tracing**: Express.js REST API with external HTTP calls
- **PostgreSQL tracing**: Database queries with pg driver
- **Kafka tracing**: Message producer and consumer
- **OpenTelemetry auto-instrumentation**: Automatic tracing for all operations
- **OTLP HTTP exporter**: Configured for Instana backend
- **Debug logging**: Console output for spans

## Prerequisites

1. **PostgreSQL** running on `localhost:5432`
- Database: `nodedb`
- User: `node`
- Password: `nodepw`

2. **Kafka** running on `localhost:9092`
- Topic: `test-topic` (will be created automatically)

3. **Instana** account with OTLP endpoint access

## Setup

### 1. Install Dependencies

```bash
npm install
```

### 2. Configure PostgreSQL

```bash
# Create database and user
psql -U postgres
CREATE DATABASE nodedb;
CREATE USER node WITH PASSWORD 'nodepw';
GRANT ALL PRIVILEGES ON DATABASE nodedb TO node;
```

### 3. Configure Kafka

Make sure Kafka is running on `localhost:9092`. If using Docker:

```bash
docker run -d --name kafka \
-p 9092:9092 \
-e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \
-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 \
confluentinc/cp-kafka:latest
```

### 4. Update Instana Configuration

Edit `tracing.js` and update:
- `url`: Your Instana OTLP endpoint
- `x-instana-key`: Your Instana API key

### 5. Start the Application

```bash
npm start
```

Or for development with auto-reload:

```bash
npm run dev
```

## API Endpoints

### 1. HTTP Entry + HTTP Exit

Tests HTTP client instrumentation with external API call.

```bash
curl http://localhost:3000/external-api
```

**Expected trace:**
- HTTP server span (Express)
- HTTP client span (fetch to jsonplaceholder.typicode.com)

### 2. HTTP Entry + PostgreSQL Exit

Tests PostgreSQL database instrumentation.

```bash
curl http://localhost:3000/db
```

**Expected trace:**
- HTTP server span (Express)
- PostgreSQL query span

### 3. HTTP Entry + Kafka Exit

Tests Kafka producer instrumentation.

```bash
curl -X POST http://localhost:3000/kafka \
-H "Content-Type: application/json" \
-d '{"message":"Hello from OpenTelemetry!"}'
```

**Expected trace:**
- HTTP server span (Express)
- Kafka producer span
- Kafka consumer span (async, separate trace)

## Tracing Details

The application automatically traces:

### HTTP Operations
- Express route handlers
- Outgoing HTTP requests (fetch/axios)
- Request/response details

### PostgreSQL Operations
- SQL queries
- Connection details
- Query parameters

### Kafka Operations
- Message production
- Message consumption
- Topic and partition information
- Custom attributes via hooks

## Viewing Traces

1. Make requests to the API endpoints
2. Check console output for span details
3. View traces in your Instana dashboard

## Troubleshooting

### PostgreSQL Connection Issues

```bash
# Check if PostgreSQL is running
pg_isready -h localhost -p 5432

# Test connection
psql -h localhost -U node -d nodedb
```

### Kafka Connection Issues

```bash
# Check if Kafka is running
nc -zv localhost 9092

# List topics
kafka-topics --list --bootstrap-server localhost:9092
```

### OpenTelemetry Issues

- Check console output for initialization messages
- Verify OTLP endpoint is accessible
- Ensure API key is correct
- Set log level to `DiagLogLevel.DEBUG` in `tracing.js` for more details

## Configuration

### Disable Console Exporter

In `tracing.js`, comment out:

```javascript
// provider.addSpanProcessor(new SimpleSpanProcessor(consoleExporter));
```

### Change Service Name

In `tracing.js`, update:

```javascript
[SemanticResourceAttributes.SERVICE_NAME]: 'your-service-name'
```

### Disable Specific Instrumentations

In `tracing.js`, modify the `getNodeAutoInstrumentations` options:

```javascript
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-fs': { enabled: false },
'@opentelemetry/instrumentation-dns': { enabled: false }
})
```

## Docker Setup (Optional)

For running PostgreSQL and Kafka in Docker:

```bash
# PostgreSQL
docker run -d --name postgres \
-e POSTGRES_USER=node \
-e POSTGRES_PASSWORD=nodepw \
-e POSTGRES_DB=nodedb \
-p 5432:5432 \
postgres:15

# Kafka (requires Zookeeper)
docker-compose up -d
```

Create a `docker-compose.yml`:

```yaml
version: '3'
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181

kafka:
image: confluentinc/cp-kafka:latest
depends_on:
- zookeeper
ports:
- "9092:9092"
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
```

## License

MIT
109 changes: 109 additions & 0 deletions example-apps/otel-exporter-test/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* (c) Copyright IBM Corp. 2026
*/

'use strict';

// Load Instana collector from local repository
require('@instana/collector')();

const express = require('express');
const { Pool } = require('pg');
const { sendKafkaMessage, startKafkaConsumer } = require('./kafka');

const app = express();
app.use(express.json());

const PORT = 3000;

const pool = new Pool({
host: 'localhost',
port: 5432,
user: 'node',
password: 'nodepw',
database: 'nodedb'
});

// ---------------------------------------------------
// 1. HTTP ENTRY + HTTP EXIT
// ---------------------------------------------------

app.get('/external-api', async (req, res) => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();

res.json({
success: true,
data
});
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);

res.status(500).json({
error: err.message
});
}
});

// ---------------------------------------------------
// 2. HTTP ENTRY + PG EXIT
// ---------------------------------------------------

app.get('/db', async (req, res) => {
try {
const result = await pool.query('SELECT NOW() as current_time');

res.json({
success: true,
rows: result.rows
});
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);

res.status(500).json({
error: err.message
});
}
});

// ---------------------------------------------------
// 3. HTTP ENTRY + KAFKA EXIT
// ---------------------------------------------------

app.post('/kafka', async (req, res) => {
try {
const payload = req.body || {
hello: 'world'
};

await sendKafkaMessage(payload);

res.json({
success: true,
sent: payload
});
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);

res.status(500).json({
error: err.message
});
}
});

// ---------------------------------------------------
// START
// ---------------------------------------------------

app.listen(PORT, async () => {
// eslint-disable-next-line no-console
console.log(`Server running on port ${PORT}`);

await startKafkaConsumer();
});

// Made with Bob
Loading