diff --git a/config.example.yaml b/config.example.yaml index e9fc7d125..199729514 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -18,10 +18,21 @@ telemetry: # tokenSecret: this-isnt-secure meters: - - slug: m1 - eventType: api-calls - valueProperty: $.duration_ms + # Sample meter to count API requests + - slug: api_requests_total # Unique identifier for the meter + description: API Requests + eventType: request # Filter events by type + aggregation: COUNT # Aggregation method: COUNT, SUM, etc. + groupBy: + method: $.method # HTTP Method: GET, POST, etc. + route: $.route # Route: /products/:product_id + + # Sample meter to count LLM Token Usage + - slug: tokens_total + description: AI Token Usage + eventType: prompt # Filter events by type aggregation: SUM + valueProperty: $.tokens # JSONPath to parse usage value groupBy: - method: $.method - path: $.path + model: $.model # AI model used: gpt4-turbo, etc. + type: $.type # Prompt type: input, output, system diff --git a/examples/ingest-logs/README.md b/examples/ingest-logs/README.md index a0912b166..3343faefa 100644 --- a/examples/ingest-logs/README.md +++ b/examples/ingest-logs/README.md @@ -18,6 +18,6 @@ Transformations in Vector uses the [Vector Remap Language](https://vector.dev/do 1. First, start OpenMeter. Refer to the [quickstart guide](/quickstart) for instructions. 2. Execute `docker compose up` within this example directory. -3. To query meters, use the following command: `curl http://localhost:8888/api/v1/meters/m1/values`. +3. To query meters, use the following command: `curl http://localhost:8888/api/v1/meters/api_requests_total/values`. Note: It's important that you run quickstart's `docker compose` first. diff --git a/quickstart/README.md b/quickstart/README.md index 027416545..5ec251c95 100644 --- a/quickstart/README.md +++ b/quickstart/README.md @@ -31,15 +31,14 @@ curl -X POST http://localhost:8888/api/v1/events \ --data-raw ' { "specversion" : "1.0", - "type": "api-calls", + "type": "request", "id": "00001", "time": "2023-01-01T00:00:00.001Z", "source": "service-0", "subject": "customer-1", "data": { - "duration_ms": "1", "method": "GET", - "path": "/hello" + "route": "/hello" } } ' @@ -53,15 +52,14 @@ curl -X POST http://localhost:8888/api/v1/events \ --data-raw ' { "specversion" : "1.0", - "type": "api-calls", + "type": "request", "id": "00002", "time": "2023-01-01T00:00:00.001Z", "source": "service-0", "subject": "customer-1", "data": { - "duration_ms": "1", "method": "GET", - "path": "/hello" + "route": "/hello" } } ' @@ -75,15 +73,14 @@ curl -X POST http://localhost:8888/api/v1/events \ --data-raw ' { "specversion" : "1.0", - "type": "api-calls", + "type": "request", "id": "00003", "time": "2023-01-02T00:00:00.001Z", "source": "service-0", "subject": "customer-1", "data": { - "duration_ms": "1", "method": "GET", - "path": "/hello" + "route": "/hello" } } ' @@ -94,7 +91,7 @@ curl -X POST http://localhost:8888/api/v1/events \ Query the usage hourly: ```sh -curl 'http://localhost:8888/api/v1/meters/m1/query?windowSize=HOUR&groupBy=method&groupBy=path' | jq +curl 'http://localhost:8888/api/v1/meters/api_requests_total/query?windowSize=HOUR&groupBy=method&groupBy=route' | jq ``` ```json @@ -108,7 +105,7 @@ curl 'http://localhost:8888/api/v1/meters/m1/query?windowSize=HOUR&groupBy=metho "subject": null, "groupBy": { "method": "GET", - "path": "/hello" + "route": "/hello" } }, { @@ -118,7 +115,7 @@ curl 'http://localhost:8888/api/v1/meters/m1/query?windowSize=HOUR&groupBy=metho "subject": null, "groupBy": { "method": "GET", - "path": "/hello" + "route": "/hello" } } ] @@ -128,7 +125,7 @@ curl 'http://localhost:8888/api/v1/meters/m1/query?windowSize=HOUR&groupBy=metho Query the total usage for `customer-1`: ```sh -curl 'http://localhost:8888/api/v1/meters/m1/query?subject=customer-1' | jq +curl 'http://localhost:8888/api/v1/meters/api_requests_total/query?subject=customer-1' | jq ``` ```json @@ -147,21 +144,25 @@ curl 'http://localhost:8888/api/v1/meters/m1/query?subject=customer-1' | jq ## 4. Configure additional meter(s) _(optional)_ -Configure how OpenMeter should process your usage events. -In this example we will meter the execution duration per API invocation, groupped by method and path. -You can think about it how AWS Lambda [charges](https://aws.amazon.com/lambda/pricing/) by execution duration on a millisecond level. +In this example we will meter LLM token usage, groupped by AI model and prompt type. +You can think about it how OpenAI [charges](https://openai.com/pricing) by tokens for ChatGPT. + +Configure how OpenMeter should process your usage events in this new `tokens_total` meter. ```yaml # ... meters: - - slug: m1 - eventType: api-calls - valueProperty: $.duration_ms + # Sample meter to count LLM Token Usage + - slug: tokens_total + description: AI Token Usage + eventType: prompt # Filter events by type aggregation: SUM + valueProperty: $.tokens # JSONPath to parse usage value groupBy: - method: $.method - path: $.path + model: $.model # AI model used: gpt4-turbo, etc. + type: $.type # Prompt type: input, output, system + ``` ## Cleanup diff --git a/quickstart/config.yaml b/quickstart/config.yaml index b44ed6791..73061bae2 100644 --- a/quickstart/config.yaml +++ b/quickstart/config.yaml @@ -11,21 +11,24 @@ sink: namespaceRefetch: 1s meters: - - slug: m1 - description: API calls - eventType: api-calls - valueProperty: $.duration_ms - aggregation: SUM + # Sample meter to count API requests + - slug: api_requests_total # Unique identifier for the meter + description: API Requests + eventType: request # Filter events by type + aggregation: COUNT # Aggregation method: COUNT, SUM, etc. groupBy: - method: $.method - path: $.path - - slug: m2 - description: Open AI Tokens - eventType: openai - valueProperty: $.total_tokens + method: $.method # HTTP Method: GET, POST, etc. + route: $.route # Route: /products/:product_id + + # Sample meter to count LLM Token Usage + - slug: tokens_total + description: AI Token Usage + eventType: prompt # Filter events by type aggregation: SUM + valueProperty: $.tokens # JSONPath to parse usage value groupBy: - model: $.model + model: $.model # AI model used: gpt4-turbo, etc. + type: $.type # Prompt type: input, output, system portal: enabled: true diff --git a/quickstart/docker-compose.yaml b/quickstart/docker-compose.yaml index 6ae198585..ca794cd90 100644 --- a/quickstart/docker-compose.yaml +++ b/quickstart/docker-compose.yaml @@ -16,7 +16,7 @@ services: volumes: - ./config.yaml:/etc/openmeter/config.yaml healthcheck: - test: wget --no-verbose --tries=1 --spider http://openmeter:8888/api/v1/meters/m1/query || exit 1 + test: wget --no-verbose --tries=1 --spider http://openmeter:8888/api/v1/meters/api_requests_total/query || exit 1 interval: 5s timeout: 3s retries: 100 diff --git a/quickstart/ingest.sh b/quickstart/ingest.sh index 3644db6d4..5b36d9933 100755 --- a/quickstart/ingest.sh +++ b/quickstart/ingest.sh @@ -5,15 +5,14 @@ curl -X POST http://localhost:8888/api/v1/events \ --data-raw ' { "specversion" : "1.0", - "type": "api-calls", + "type": "request", "id": "00001", "time": "2023-01-01T00:00:00.001Z", "source": "service-0", "subject": "customer-1", "data": { - "duration_ms": "1", "method": "GET", - "path": "/hello" + "route": "/hello" } } ' @@ -23,15 +22,14 @@ curl -X POST http://localhost:8888/api/v1/events \ --data-raw ' { "specversion" : "1.0", - "type": "api-calls", + "type": "request", "id": "00002", "time": "2023-01-01T00:00:00.001Z", "source": "service-0", "subject": "customer-1", "data": { - "duration_ms": "1", "method": "GET", - "path": "/hello" + "route": "/hello" } } ' @@ -41,15 +39,14 @@ curl -X POST http://localhost:8888/api/v1/events \ --data-raw ' { "specversion" : "1.0", - "type": "api-calls", + "type": "request", "id": "00003", "time": "2023-01-02T00:00:00.001Z", "source": "service-0", "subject": "customer-1", "data": { - "duration_ms": "1", "method": "GET", - "path": "/hello" + "route": "/hello" } } ' diff --git a/quickstart/verify.sh b/quickstart/verify.sh index 1f27a9b45..1b1fbae6c 100755 --- a/quickstart/verify.sh +++ b/quickstart/verify.sh @@ -2,7 +2,7 @@ temp_file=$(mktemp) -curl http://localhost:8888/api/v1/meters/m1/query?windowSize=HOUR >$temp_file +curl http://localhost:8888/api/v1/meters/api_requests_total/query?windowSize=HOUR >$temp_file [ $(cat $temp_file | jq '.data[0].value') == 2 ] || (echo "Unexpected value" && cat $temp_file && exit 1) [ $(cat $temp_file | jq '.data[1].value') == 1 ] || (echo "Unexpected value" && cat $temp_file && exit 1)