Skip to content

Commit

Permalink
Merge branch 'main' into Add-otel-log-support-to-payment-service
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimbohlovette authored Apr 22, 2024
2 parents 20fb399 + 8b1e260 commit 08d0d7d
Show file tree
Hide file tree
Showing 18 changed files with 98 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gradle-wrapper-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: gradle/wrapper-validation-action@v2.1.2
- uses: gradle/wrapper-validation-action@v3.3.1
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ the release.
([#1507](https://github.com/open-telemetry/opentelemetry-demo/pull/1507))
* [cartservice] update .NET package to 1.8.0 release
([#1514](https://github.com/open-telemetry/opentelemetry-demo/pull/1514))
* [quoteservice] add manual metric, export logs periodically
([#1519](https://github.com/open-telemetry/opentelemetry-demo/pull/1519))
* [flagd] export flagd traces to otel collector
([#1522](https://github.com/open-telemetry/opentelemetry-demo/pull/1522))
* [frontend] Pass down image optimization requests to imageprovider
([#1522](https://github.com/open-telemetry/opentelemetry-demo/pull/1522))

## 1.9.0

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ start:
@echo "Go to http://localhost:8080/jaeger/ui for the Jaeger UI."
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to https://opentelemetry.io/docs/demo/feature-flags/ to learn how to change feature flags."

.PHONY: start-minimal
start-minimal:
Expand All @@ -141,6 +142,7 @@ start-minimal:
@echo "Go to http://localhost:8080/jaeger/ui for the Jaeger UI."
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to https://opentelemetry.io/docs/demo/feature-flags/ to learn how to change feature flags."

# Observabilty-Driven Development (ODD)
.PHONY: start-odd
Expand All @@ -153,6 +155,7 @@ start-odd:
@echo "Go to http://localhost:8080/grafana/ for the Grafana UI."
@echo "Go to http://localhost:8080/loadgen/ for the Load Generator UI."
@echo "Go to http://localhost:11633/ for the Tracetest Web UI."
@echo "Go to https://opentelemetry.io/docs/demo/feature-flags/ to learn how to change feature flags."

.PHONY: stop
stop:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Emeritus:
[Azure]: https://github.com/Azure/Azure-kusto-opentelemetry-demo
[Coralogix]: https://coralogix.com/blog/configure-otel-demo-send-telemetry-data-coralogix
[Dash0]: https://github.com/dash0hq/opentelemetry-demo
[Datadog]: https://github.com/DataDog/opentelemetry-demo
[Datadog]: https://docs.datadoghq.com/opentelemetry/guide/otel_demo_to_datadog
[Dynatrace]: https://www.dynatrace.com/news/blog/opentelemetry-demo-application-with-dynatrace/
[Elastic]: https://github.com/elastic/opentelemetry-demo
[GoogleCloud]: https://github.com/GoogleCloudPlatform/opentelemetry-demo
Expand Down
1 change: 1 addition & 0 deletions docker-compose.minimal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ services:
- OTEL_RESOURCE_ATTRIBUTES
- OTEL_SERVICE_NAME=loadgenerator
- PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
- LOCUST_WEB_HOST=0.0.0.0
- FLAGD_HOST
- FLAGD_PORT
depends_on:
Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ services:
flagd:
image: ghcr.io/open-feature/flagd:v0.9.0
container_name: flagd
environment:
- FLAGD_OTEL_COLLECTOR_URI=${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_GRPC}
- FLAGD_METRICS_EXPORTER=otel
- OTEL_RESOURCE_ATTRIBUTES
- OTEL_SERVICE_NAME=flagd
command: [
"start",
"--uri",
Expand Down Expand Up @@ -412,6 +417,7 @@ services:
- OTEL_RESOURCE_ATTRIBUTES
- OTEL_SERVICE_NAME=loadgenerator
- PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
- LOCUST_WEB_HOST=0.0.0.0
- FLAGD_HOST
- FLAGD_PORT
depends_on:
Expand Down
4 changes: 2 additions & 2 deletions src/adservice/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FROM eclipse-temurin:21-jdk as builder

WORKDIR /usr/src/app/

COPY ./src/adservice/gradlew* ./src/adservice/settings.gradle* ./src/adservice/build.gradle .
COPY ./src/adservice/gradlew* ./src/adservice/settings.gradle* ./src/adservice/build.gradle ./
COPY ./src/adservice/gradle ./gradle

RUN ./gradlew
Expand All @@ -20,7 +20,7 @@ RUN ./gradlew installDist -PprotoSourceDir=./proto

FROM eclipse-temurin:21-jre

ARG version=2.0.0
ARG version=2.3.0
WORKDIR /usr/src/app/

COPY --from=builder /usr/src/app/ ./
Expand Down
21 changes: 15 additions & 6 deletions src/adservice/src/main/java/oteldemo/AdService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
import io.grpc.protobuf.services.*;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
import io.opentelemetry.instrumentation.annotations.WithSpan;
Expand Down Expand Up @@ -132,7 +135,8 @@ private static class AdServiceImpl extends oteldemo.AdServiceGrpc.AdServiceImplB
private static final String ADSERVICE_FAILURE = "adServiceFailure";
private static final String ADSERVICE_MANUAL_GC_FEATURE_FLAG = "adServiceManualGc";
private static final String ADSERVICE_HIGH_CPU_FEATURE_FLAG = "adServiceHighCpu";

Client ffClient = OpenFeatureAPI.getInstance().getClient();

private AdServiceImpl() {}

/**
Expand All @@ -155,6 +159,15 @@ public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
AdRequestType adRequestType;
AdResponseType adResponseType;

Baggage baggage = Baggage.fromContextOrNull(Context.current());
if (baggage != null) {
final String sessionId = baggage.getEntryValue("session.id");
span.setAttribute("session.id", sessionId);
ffClient.setEvaluationContext(new MutableContext().add("session", sessionId));
} else {
logger.info("no baggage found in context");
}

span.setAttribute("app.ads.contextKeys", req.getContextKeysList().toString());
span.setAttribute("app.ads.contextKeys.count", req.getContextKeysCount());
if (req.getContextKeysCount() > 0) {
Expand Down Expand Up @@ -214,11 +227,7 @@ public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
* @return {@code true} if the feature flag is enabled, {@code false} otherwise or in case of errors.
*/
boolean getFeatureFlagEnabled(String ff) {
Client client = OpenFeatureAPI.getInstance().getClient();
// TODO: Plumb the actual session ID from the frontend via baggage?
UUID uuid = UUID.randomUUID();
client.setEvaluationContext(new MutableContext().add("session", uuid.toString()));
Boolean boolValue = client.getBooleanValue(ff, false);
Boolean boolValue = ffClient.getBooleanValue(ff, false);
return boolValue;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/frauddetectionservice/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ RUN gradle shadowJar

FROM gcr.io/distroless/java17-debian11

ARG version=2.0.0
ARG version=2.3.0
WORKDIR /usr/src/app/

COPY --from=builder /usr/src/app/build/libs/frauddetectionservice-1.0-all.jar ./
Expand Down
26 changes: 25 additions & 1 deletion src/frontend/components/CheckoutItem/CheckoutItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@ interface IProps {
address: Address;
}

interface ImageLoaderProps {
src: string;
width: number;
quality?: number;
}
/**
* We connect to imageprovider through the envoy proxy, straight from the browser, for this we need to know the current hostname and port.
* During building and serverside rendering, these are undefined so we use some conditionals and default values.
*/
let hostname = "";
let port = 80;
let protocol = "http";

if (typeof window !== "undefined" && window.location) {
hostname = window.location.hostname;
port = window.location.port ? parseInt(window.location.port, 10) : (window.location.protocol === "https:" ? 443 : 80);
protocol = window.location.protocol.slice(0, -1); // Remove trailing ':'
}
const imageLoader = ({ src, width, quality }: ImageLoaderProps): string => {
// We pass down the optimization request to the iamgeprovider service here, without this, nextJs would trz to use internal optimizer which is not working with the external imageprovider.
return `${protocol}://${hostname}:${port}/${src}?w=${width}&q=${quality || 75}`;
}


const CheckoutItem = ({
checkoutItem: {
item: {
Expand All @@ -29,7 +53,7 @@ const CheckoutItem = ({
return (
<S.CheckoutItem data-cy={CypressFields.CheckoutItem}>
<S.ItemDetails>
<S.ItemImage src={"/images/products/" + picture} alt={name} />
<S.ItemImage src={"/images/products/" + picture} alt={name} loader={imageLoader}/>
<S.Details>
<S.ItemName>{name}</S.ItemName>
<p>Quantity: {quantity}</p>
Expand Down
19 changes: 14 additions & 5 deletions src/frontend/gateways/Api.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import { Ad, Address, Cart, CartItem, Money, PlaceOrderRequest, Product } from '../protos/demo';
import { IProductCart, IProductCartItem, IProductCheckout } from '../types/Cart';
import request from '../utils/Request';
import { AttributeNames } from '../utils/enums/AttributeNames';
import SessionGateway from './Session.gateway';
import { context, propagation } from "@opentelemetry/api";

const { userId } = SessionGateway.getSession();

Expand Down Expand Up @@ -82,11 +84,18 @@ const ApiGateway = () => ({
});
},
listAds(contextKeys: string[]) {
return request<Ad[]>({
url: `${basePath}/data`,
queryParams: {
contextKeys,
},
// TODO: Figure out a better way to do this so session ID gets propagated to
// all endpoints
const baggage = propagation.getActiveBaggage() || propagation.createBaggage();
const newBaggage = baggage.setEntry(AttributeNames.SESSION_ID, { value: userId });
const newContext = propagation.setBaggage(context.active(), newBaggage);
context.with(newContext, () => {
return request<Ad[]>({
url: `${basePath}/data`,
queryParams: {
contextKeys,
},
});
});
},
});
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/providers/Ad.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ const AdProvider = ({ children, productIds, contextKeys }: IProps) => {
const { selectedCurrency } = useCurrency();
const { data: adList = [] } = useQuery(
['ads', contextKeys],
() => {
async () => {
if (contextKeys.length === 0) {
return Promise.resolve([]);
return [];
} else {
return ApiGateway.listAds(contextKeys);
}
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/utils/enums/AttributeNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// SPDX-License-Identifier: Apache-2.0

export enum AttributeNames {
SESSION_ID = 'app.session.id'
SESSION_ID = 'session.id'
}
11 changes: 10 additions & 1 deletion src/quoteservice/app/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,20 @@ function calculateQuote($jsonObject): float
throw new \InvalidArgumentException('numberOfItems not provided');
}
$numberOfItems = intval($jsonObject['numberOfItems']);
$quote = round(8.90 * $numberOfItems, 2);
$costPerItem = rand(400, 1000)/10;
$quote = round($costPerItem * $numberOfItems, 2);

$childSpan->setAttribute('app.quote.items.count', $numberOfItems);
$childSpan->setAttribute('app.quote.cost.total', $quote);

$childSpan->addEvent('Quote calculated, returning its value');

//manual metrics
static $counter;
$counter ??= Globals::meterProvider()
->getMeter('quotes')
->createCounter('quotes', 'quotes', 'number of quotes calculated');
$counter->add(1, ['number_of_items' => $numberOfItems]);
} catch (\Exception $exception) {
$childSpan->recordException($exception);
} finally {
Expand All @@ -55,6 +63,7 @@ function calculateQuote($jsonObject): float
$span->addEvent('Quote processed, response sent back', [
'app.quote.cost.total' => $data
]);
//exported as an opentelemetry log (see dependencies.php)
$logger->info('Calculated quote', [
'total' => $data,
]);
Expand Down
4 changes: 2 additions & 2 deletions src/quoteservice/app/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use App\Application\Settings\Settings;
use App\Application\Settings\SettingsInterface;
use DI\ContainerBuilder;
use Monolog\Logger;
use Psr\Log\LogLevel;

return function (ContainerBuilder $containerBuilder) {
// Global Settings Object
Expand All @@ -22,7 +22,7 @@
'logger' => [
'name' => 'slim-app',
'path' => 'php://stdout',
'level' => Logger::DEBUG,
'level' => LogLevel::DEBUG,
],
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/quoteservice/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"monolog/monolog": "3.5.0",
"open-telemetry/api": "1.0.3",
"open-telemetry/sdk": "1.0.8",
"open-telemetry/exporter-otlp": "1.0.3",
"open-telemetry/exporter-otlp": "1.0.4",
"open-telemetry/opentelemetry-auto-slim": "1.0.4",
"open-telemetry/detector-container": "1.0.0",
"open-telemetry/opentelemetry-logger-monolog": "1.0.0",
Expand Down
6 changes: 6 additions & 0 deletions src/quoteservice/public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use OpenTelemetry\API\Globals;
use OpenTelemetry\SDK\Common\Configuration\Configuration;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\Logs\LoggerProviderInterface;
use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
use OpenTelemetry\SDK\Trace\TracerProviderInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand Down Expand Up @@ -61,6 +62,11 @@
$tracerProvider->forceFlush();
});
}
if (($loggerProvider = Globals::loggerProvider()) instanceof LoggerProviderInterface) {
Loop::addPeriodicTimer(Configuration::getInt(Variables::OTEL_BLRP_SCHEDULE_DELAY)/1000, function() use ($loggerProvider) {
$loggerProvider->forceFlush();
});
}
if (($meterProvider = Globals::meterProvider()) instanceof MeterProviderInterface) {
Loop::addPeriodicTimer(Configuration::getInt(Variables::OTEL_METRIC_EXPORT_INTERVAL)/1000, function() use ($meterProvider) {
$meterProvider->forceFlush();
Expand Down
3 changes: 1 addition & 2 deletions test/tracetesting/shipping-service/quote.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,4 @@ spec:
selector: span[tracetest.span.type="general" name="Tracetest trigger"]
assertions:
- attr:tracetest.response.body | json_path '$.costUsd.currencyCode' = "USD"
- attr:tracetest.response.body | json_path '$.costUsd.units' = 17
- attr:tracetest.response.body | json_path '$.costUsd.nanos' = 800000000
- attr:tracetest.response.body | json_path '$.costUsd.units' > 0

0 comments on commit 08d0d7d

Please sign in to comment.