广告服务

该服务基于上下文关键字来确定要向用户展示的广告。这些广告是商店中可用的产品。

广告服务源代码

自动仪表化

该服务依赖于 OpenTelemetry Java 代理自动对诸如 gRPC 等库进行仪表化,并配置 OpenTelemetry SDK. 代理使用 -javaagent 命令行参数传递给进程。命令行参数在 Dockerfile 中通过 JAVA_TOOL_OPTIONS 添加,并在自动生成的 Gradle 启动脚本中使用。

ENV JAVA_TOOL_OPTIONS=-javaagent:/app/opentelemetry-javaagent.jar

追踪

为自动仪表化 Span 添加属性

在自动仪表化代码的执行过程中,您可以从上下文获取当前的 Span。

Span span = Span.current();

向一个 Span 添加属性可通过在 Span 对象上使用 setAttribute 来完成。在 getAds 函数中,多个属性被添加到 Span 中。

span.setAttribute("app.ads.contextKeys", req.getContextKeysList().toString());
span.setAttribute("app.ads.contextKeys.count", req.getContextKeysCount());

添加 Span 事件

向 Span 添加事件可通过在 Span 对象上使用 addEvent 来完成。在 getAds 函数中,当捕获到异常时,会添加一个带有属性的事件。

span.addEvent("Error", Attributes.of(AttributeKey.stringKey("exception.message"), e.getMessage()));

设置 Span 状态

如果操作的结果是错误的,应使用 setStatus 在 Span 对象上设置相应的状态。在 getAds 函数中,当捕获到异常时会设置 Span 的状态。

span.setStatus(StatusCode.ERROR);

创建新的 Span

可以使用 Tracer.spanBuilder("spanName").startSpan() 创建并启动新的 Span。新创建的 Span 应使用 Span.makeCurrent() 设置到上下文中。getRandomAds 函数将创建一个新的 Span,将其设置到上下文中,执行操作,最后结束该 Span。

// 手动创建并启动新的 Span
Tracer tracer = GlobalOpenTelemetry.getTracer("adservice");
Span span = tracer.spanBuilder("getRandomAds").startSpan();

// 将 Span 设置到上下文中,这样如果有任何子 Span 被启动,父 Span 将被正确设置
try (Scope ignored = span.makeCurrent()) {

  Collection<Ad> allAds = adsMap.values();
  for (int i = 0; i < MAX_ADS_TO_SERVE; i++) {
    ads.add(Iterables.get(allAds, random.nextInt(allAds.size())));
  }
  span.setAttribute("app.ads.count", ads.size());

} finally {
  span.end();
}

指标

初始化指标

与创建 Span 类似,创建指标的第一步是初始化一个 Meter 实例,例如 GlobalOpenTelemetry.getMeter("adservice")。然后,使用 Meter 实例上的各种构建器方法来创建所需的指标工具,例如:

meter
  .counterBuilder("app.ads.ad_requests")
  .setDescription("统计按请求和响应类型的广告请求数量")
  .build();

目前生成的指标

请注意,下面所有的指标名称在 Prometheus/Grafana 中会将 . 字符转换为 _

自定义指标

目前可用的自定义指标如下:

  • app.ads.ad_requests: 描述请求是否针对上下文关键字以及响应是否针对定向广告或随机广告的计数器。

自动仪表化指标

以下自动仪表化的指标适用于该应用程序:

日志

待定

最后修改 December 10, 2023: translate (a4350d6e)