diff --git a/.github/workflows/label-pr.yml b/.github/workflows/label-pr.yml index fe3974c18b..e027769190 100644 --- a/.github/workflows/label-pr.yml +++ b/.github/workflows/label-pr.yml @@ -4,12 +4,15 @@ name: Label Pull Requests on: - pull_request: + pull_request_target: types: [opened, synchronize, reopened] jobs: label: runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: read steps: - name: Checkout uses: actions/checkout@v2 @@ -34,10 +37,9 @@ jobs: if: steps.file_changes.outputs.docsUpdateRequired == 'true' uses: actions/github-script@v7 with: - github-token: ${{secrets.GITHUB_TOKEN}} script: | const issue_number = context.issue.number; - github.issues.addLabels({ + github.rest.issues.addLabels({ issue_number: issue_number, owner: context.repo.owner, repo: context.repo.repo, @@ -48,10 +50,9 @@ jobs: if: steps.file_changes.outputs.helmUpdateRequired == 'true' uses: actions/github-script@v7 with: - github-token: ${{secrets.GITHUB_TOKEN}} script: | const issue_number = context.issue.number; - github.issues.addLabels({ + github.rest.issues.addLabels({ issue_number: issue_number, owner: context.repo.owner, repo: context.repo.repo, diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d437a8704..7e0b49e479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ the release. * [frauddetectionservice] use span links when consuming from Kafka ([#1501](https://github.com/open-telemetry/opentelemetry-demo/pull/1501)) +* [frontend] reunite trace from loadgenerator + ([#1506](https://github.com/open-telemetry/opentelemetry-demo/pull/1506)) ## 1.9.0 @@ -59,6 +61,8 @@ the release. ([#1473](https://github.com/open-telemetry/opentelemetry-demo/pull/1473)) * [Imageprovider] Create Nginx service to host images, add instrumentation to it ([#1462](https://github.com/open-telemetry/opentelemetry-demo/pull/1462)) +* [loadgenerator] added loadgeneratorFloodHomepage flagd + ([#1486](https://github.com/open-telemetry/opentelemetry-demo/pull/1486)) ## 1.8.0 diff --git a/docker-compose.minimal.yml b/docker-compose.minimal.yml index 88408a9434..1a5c211672 100644 --- a/docker-compose.minimal.yml +++ b/docker-compose.minimal.yml @@ -331,9 +331,13 @@ services: - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=loadgenerator - PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + - FLAGD_HOST + - FLAGD_PORT depends_on: frontend: condition: service_started + flagd: + condition: service_started logging: *logging # Payment service diff --git a/docker-compose.yml b/docker-compose.yml index d36fe64de3..c52c34d37a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -412,9 +412,13 @@ services: - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=loadgenerator - PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + - FLAGD_HOST + - FLAGD_PORT depends_on: frontend: condition: service_started + flagd: + condition: service_started logging: *logging # Payment service diff --git a/src/flagd/demo.flagd.json b/src/flagd/demo.flagd.json index 26c2c71b94..6d2dac0d83 100644 --- a/src/flagd/demo.flagd.json +++ b/src/flagd/demo.flagd.json @@ -78,6 +78,15 @@ "off": false }, "defaultVariant": "off" + }, + "loadgeneratorFloodHomepage": { + "description": "Flood the frontend with a large amount of requests.", + "state": "ENABLED", + "variants": { + "on": 100, + "off": 0 + }, + "defaultVariant": "off" } } } diff --git a/src/frontend/utils/telemetry/InstrumentationMiddleware.ts b/src/frontend/utils/telemetry/InstrumentationMiddleware.ts index 1c1fde12c5..ed389aff8d 100644 --- a/src/frontend/utils/telemetry/InstrumentationMiddleware.ts +++ b/src/frontend/utils/telemetry/InstrumentationMiddleware.ts @@ -2,47 +2,19 @@ // SPDX-License-Identifier: Apache-2.0 import { NextApiHandler } from 'next'; -import { context, Exception, propagation, Span, SpanKind, SpanStatusCode, trace } from '@opentelemetry/api'; +import {context, Exception, Span, SpanStatusCode, trace} from '@opentelemetry/api'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; import { metrics } from '@opentelemetry/api'; -import { AttributeNames } from '../enums/AttributeNames'; const meter = metrics.getMeter('frontend'); const requestCounter = meter.createCounter('app.frontend.requests'); const InstrumentationMiddleware = (handler: NextApiHandler): NextApiHandler => { return async (request, response) => { - const { headers, method, url = '', httpVersion } = request; + const {method, url = ''} = request; const [target] = url.split('?'); - let span; - const baggage = propagation.getBaggage(context.active()); - if (baggage?.getEntry('synthetic_request')?.value == 'true') { - // if synthetic_request baggage is set, create a new trace linked to the span in context - // this span will look similar to the auto-instrumented HTTP span - const syntheticSpan = trace.getSpan(context.active()) as Span; - const tracer = trace.getTracer(process.env.OTEL_SERVICE_NAME as string); - span = tracer.startSpan(`HTTP ${method}`, { - root: true, - kind: SpanKind.SERVER, - links: [{ context: syntheticSpan.spanContext() }], - attributes: { - 'app.synthetic_request': true, - [SemanticAttributes.HTTP_TARGET]: target, - [SemanticAttributes.HTTP_METHOD]: method, - [SemanticAttributes.HTTP_USER_AGENT]: headers['user-agent'] || '', - [SemanticAttributes.HTTP_URL]: `${headers.host}${url}`, - [SemanticAttributes.HTTP_FLAVOR]: httpVersion, - }, - }); - } else { - // continue current trace/span - span = trace.getSpan(context.active()) as Span; - } - - if (request.query['sessionId'] != null) { - span.setAttribute(AttributeNames.SESSION_ID, request.query['sessionId']); - } + const span = trace.getSpan(context.active()) as Span; let httpStatus = 200; try { @@ -56,9 +28,6 @@ const InstrumentationMiddleware = (handler: NextApiHandler): NextApiHandler => { } finally { requestCounter.add(1, { method, target, status: httpStatus }); span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, httpStatus); - if (baggage?.getEntry('synthetic_request')?.value == 'true') { - span.end(); - } } }; }; diff --git a/src/loadgenerator/locustfile.py b/src/loadgenerator/locustfile.py index 9375df2d00..77c33796c8 100644 --- a/src/loadgenerator/locustfile.py +++ b/src/loadgenerator/locustfile.py @@ -33,6 +33,11 @@ from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler from opentelemetry.sdk._logs.export import BatchLogRecordProcessor from opentelemetry.sdk.resources import Resource + +from openfeature import api +from openfeature.contrib.provider.flagd import FlagdProvider +from openfeature.exception import OpenFeatureError + from playwright.async_api import Route, Request logger_provider = LoggerProvider(resource=Resource.create( @@ -64,6 +69,14 @@ URLLib3Instrumentor().instrument() logging.info("Instrumentation complete") +# Initialize Flagd provider +api.set_provider(FlagdProvider(host=os.environ.get('FLAGD_HOST', 'flagd'), port=os.environ.get('FLAGD_PORT', 8013))) + +def get_flagd_value(FlagName): + # Initialize OpenFeature + client = api.get_client() + return client.get_integer_value(FlagName, 0) + categories = [ "binoculars", "telescopes", @@ -153,6 +166,11 @@ def checkout_multi(self): checkout_person["userId"] = user self.client.post("/api/checkout", json=checkout_person) + @task(5) + def flood_home(self): + for _ in range(0, get_flagd_value("loadgeneratorFloodHomepage")): + self.client.get("/") + def on_start(self): ctx = baggage.set_baggage("synthetic_request", "true") context.attach(ctx) diff --git a/src/loadgenerator/requirements.txt b/src/loadgenerator/requirements.txt index 88aba3fdc3..2c7f3601e1 100644 --- a/src/loadgenerator/requirements.txt +++ b/src/loadgenerator/requirements.txt @@ -30,7 +30,9 @@ opentelemetry-proto==1.23.0 opentelemetry-sdk==1.23.0 opentelemetry-semantic-conventions==0.44b0 opentelemetry-util-http==0.44b0 -protobuf==4.25.0 +openfeature-sdk==0.5.0 +openfeature-provider-flagd==0.1.3 +protobuf==4.25.2 psutil==5.9.6 pyzmq==25.1.1 requests==2.31.0