Skip to content

Commit 8cd8373

Browse files
Added x-source-ui header, logged in http server metrics (#3581)
--------- Signed-off-by: Raymond Roestenburg <raymond.roestenburg@digitalasset.com>
1 parent 4541f20 commit 8cd8373

File tree

12 files changed

+111
-51
lines changed

12 files changed

+111
-51
lines changed

apps/app/src/main/scala/org/lfdecentralizedtrust/splice/metrics/SpliceMetricsFactory.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ case class SpliceMetricsFactory(
3333
new ValidatorAppMetrics(
3434
metricsFactoryProvider.generateMetricsFactory(metricsContext),
3535
storageHistograms,
36+
loggerFactory,
3637
)
3738
},
3839
)
@@ -45,6 +46,7 @@ case class SpliceMetricsFactory(
4546
new SvAppMetrics(
4647
metricsFactoryProvider.generateMetricsFactory(metricsContext),
4748
storageHistograms,
49+
loggerFactory,
4850
)
4951
},
5052
)
@@ -71,9 +73,9 @@ case class SpliceMetricsFactory(
7173
new SplitwellAppMetrics(
7274
metricsFactoryProvider.generateMetricsFactory(metricsContext),
7375
storageHistograms,
76+
loggerFactory,
7477
)
7578
},
7679
)
7780
}
78-
7981
}

apps/common/frontend/src/api/scan/ScanClientContext.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ export const ScanClientProvider: React.FC<React.PropsWithChildren<ScanProps>> =
1919
const client: openapi.ScanApi | undefined = useMemo(() => {
2020
const configuration = openapi.createConfiguration({
2121
baseServer: new openapi.ServerConfiguration(url, {}),
22-
promiseMiddleware: [new OpenAPILoggingMiddleware('scan')],
22+
promiseMiddleware: [
23+
new OpenAPILoggingMiddleware('scan'),
24+
{
25+
pre: async context => {
26+
context.setHeaderParam('x-source-ui', 'scan');
27+
return context;
28+
},
29+
post: async context => context,
30+
},
31+
],
2332
});
2433

2534
return new openapi.ScanApi(configuration);

apps/common/src/main/scala/org/lfdecentralizedtrust/splice/SpliceMetrics.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.daml.metrics.HealthMetrics
77
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
88
import com.daml.metrics.api.{MetricName, MetricsContext}
99
import com.digitalasset.canton.environment.BaseMetrics
10+
import com.digitalasset.canton.logging.NamedLoggerFactory
1011
import com.digitalasset.canton.metrics.ActiveRequestsMetrics.GrpcServerMetricsX
1112
import com.digitalasset.canton.metrics.{
1213
DbStorageHistograms,
@@ -33,6 +34,7 @@ abstract class BaseSpliceMetrics(
3334
nodeType: String,
3435
override val openTelemetryMetricsFactory: LabeledMetricsFactory,
3536
storageHistograms: DbStorageHistograms,
37+
loggerFactory: NamedLoggerFactory,
3638
) extends SpliceMetrics {
3739

3840
override val prefix = MetricName(nodeType)
@@ -48,7 +50,8 @@ abstract class BaseSpliceMetrics(
4850
new DbStorageMetrics(storageHistograms, openTelemetryMetricsFactory)
4951

5052
override def httpServerMetrics: HttpServerMetrics = new HttpServerMetrics(
51-
openTelemetryMetricsFactory
53+
openTelemetryMetricsFactory,
54+
loggerFactory,
5255
)
5356
override def httpClientMetrics: HttpClientMetrics = new HttpClientMetrics(
5457
openTelemetryMetricsFactory

apps/common/src/main/scala/org/lfdecentralizedtrust/splice/http/HttpServerMetrics.scala

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,29 @@ package org.lfdecentralizedtrust.splice.http
66
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
77
import com.daml.metrics.api.MetricQualification.Latency
88
import com.daml.metrics.api.{MetricInfo, MetricName, MetricsContext}
9+
import com.digitalasset.canton.logging.{NamedLoggerFactory, NamedLogging}
10+
import com.digitalasset.canton.tracing.TraceContext
911
import org.apache.pekko.http.scaladsl.server.{Directive0, RouteResult}
1012

1113
import scala.util.{Failure, Success}
1214

13-
class HttpServerMetrics(metricsFactory: LabeledMetricsFactory) {
15+
object HttpServerMetrics {
16+
val customSourceUiHeader = "x-source-ui"
17+
object LabelNames {
18+
val Operation = "operation"
19+
val Status = "status"
20+
val StatusCode = "status_code"
21+
val HttpService = "http_service"
22+
val SourceUi = "source_ui"
23+
}
24+
}
25+
26+
class HttpServerMetrics(
27+
metricsFactory: LabeledMetricsFactory,
28+
override protected val loggerFactory: NamedLoggerFactory,
29+
) extends NamedLogging {
30+
import HttpServerMetrics.*
31+
import HttpServerMetrics.LabelNames.*
1432

1533
private val prefix: MetricName = MetricName.Daml :+ "http"
1634

@@ -20,8 +38,8 @@ class HttpServerMetrics(metricsFactory: LabeledMetricsFactory) {
2038
summary = "Histogram for http request durations",
2139
qualification = Latency,
2240
labelsWithDescription = Map(
23-
"operation" -> "Descriptor of the HTTP operation done, as per the OpenAPI spec",
24-
"status" -> "Status of the HTTP request: completed, rejected, failure",
41+
Operation -> "Descriptor of the HTTP operation done, as per the OpenAPI spec",
42+
Status -> "Status of the HTTP request: completed, rejected, failure",
2543
),
2644
)
2745
)
@@ -32,38 +50,53 @@ class HttpServerMetrics(metricsFactory: LabeledMetricsFactory) {
3250
summary = "Count of in-flight http requests",
3351
qualification = Latency,
3452
labelsWithDescription = Map(
35-
"operation" -> "Descriptor of the HTTP operation done, as per the OpenAPI spec"
53+
Operation -> "Descriptor of the HTTP operation done, as per the OpenAPI spec"
3654
),
3755
)
3856
)
3957

4058
// This directive is used to wrap HTTP routes with metrics collection.
4159
// We need to pass the operation explicitly, which represents the OpenAPI operation ID.
42-
def withMetrics(service: String)(operation: String): Directive0 = {
60+
def withMetrics(service: String)(operation: String)(implicit tc: TraceContext): Directive0 = {
4361
import org.apache.pekko.http.scaladsl.server.Directives.*
44-
implicit val mc: MetricsContext =
45-
MetricsContext("operation" -> operation, "http_service" -> service)
4662

4763
extractExecutionContext.flatMap { implicit ec =>
48-
extractRequest.flatMap { _ =>
64+
extractRequest.flatMap { req =>
65+
val c = MetricsContext(Operation -> operation, HttpService -> service)
66+
implicit val mc: MetricsContext = req.headers
67+
.find(_.is(customSourceUiHeader)) // custom header added by the UI
68+
.map { header =>
69+
val sourceUi = header.value
70+
logger.debug(
71+
s"HTTP Request from UI($customSourceUiHeader: $sourceUi): service = $service, operation= $operation"
72+
)
73+
c.withExtraLabels(SourceUi -> sourceUi)
74+
}
75+
.getOrElse {
76+
logger.debug(
77+
s"HTTP Request no source UI header: service = $service, operation= $operation"
78+
)
79+
c
80+
}
81+
4982
inFlightRequests.inc()
5083
val timing = requestTiming.startAsync()
5184
mapRouteResultFuture { resultFuture =>
5285
resultFuture.map[RouteResult] {
5386
case res @ RouteResult.Complete(response) =>
5487
timing.stop()(
5588
MetricsContext(
56-
"status_code" -> response.status.intValue().toString,
57-
"status" -> "completed",
89+
StatusCode -> response.status.intValue().toString,
90+
Status -> "completed",
5891
)
5992
)
6093
res
6194
case res @ RouteResult.Rejected(_) =>
62-
timing.stop()(MetricsContext("status" -> "rejected"))
95+
timing.stop()(MetricsContext(Status -> "rejected"))
6396
res
6497
} andThen {
6598
case Failure(_) =>
66-
timing.stop()(MetricsContext("status" -> "failure"))
99+
timing.stop()(MetricsContext(Status -> "failure"))
67100
inFlightRequests.dec()
68101
case Success(_) =>
69102
inFlightRequests.dec()

apps/scan/frontend/src/api/TokenMetadataClientContext.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,16 @@ export const TokenMetadataClientProvider: React.FC<React.PropsWithChildren<ScanC
1818
const client: openapi.DefaultApi | undefined = useMemo(() => {
1919
const configuration = openapi.createConfiguration({
2020
baseServer: new openapi.ServerConfiguration(scanUrl, {}),
21-
promiseMiddleware: [new OpenAPILoggingMiddleware('TokenMetadata')],
21+
promiseMiddleware: [
22+
new OpenAPILoggingMiddleware('TokenMetadata'),
23+
{
24+
pre: async context => {
25+
context.setHeaderParam('x-source-ui', 'scan');
26+
return context;
27+
},
28+
post: async context => context,
29+
},
30+
],
2231
});
2332

2433
return new openapi.DefaultApi(configuration);

apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/ScanAppMetrics.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ScanAppMetrics(
1919
storageHistograms: DbStorageHistograms,
2020
loggerFactory: NamedLoggerFactory,
2121
timeouts: ProcessingTimeout,
22-
) extends BaseSpliceMetrics("scan", metricsFactory, storageHistograms) {
22+
) extends BaseSpliceMetrics("scan", metricsFactory, storageHistograms, loggerFactory) {
2323
val dbScanStore = new DbScanStoreMetrics(metricsFactory, loggerFactory, timeouts)
2424
val verdictIngestion = new ScanMediatorVerdictIngestionMetrics(metricsFactory)
2525
}

apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/metrics/SplitwellAppMetrics.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package org.lfdecentralizedtrust.splice.splitwell.metrics
55

66
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
7+
import com.digitalasset.canton.logging.NamedLoggerFactory
78
import org.lfdecentralizedtrust.splice.BaseSpliceMetrics
89
import com.digitalasset.canton.metrics.DbStorageHistograms
910

@@ -14,4 +15,5 @@ import com.digitalasset.canton.metrics.DbStorageHistograms
1415
class SplitwellAppMetrics(
1516
metricsFactory: LabeledMetricsFactory,
1617
storageHistograms: DbStorageHistograms,
17-
) extends BaseSpliceMetrics("splitwell", metricsFactory, storageHistograms) {}
18+
loggerFactory: NamedLoggerFactory,
19+
) extends BaseSpliceMetrics("splitwell", metricsFactory, storageHistograms, loggerFactory) {}

apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/SvApp.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ class SvApp(
634634
val errorHandler = new HttpErrorHandler(loggerFactory)
635635
def buildOperation(service: String, operation: String) = {
636636
metrics.httpServerMetrics
637-
.withMetrics(service)(operation)
637+
.withMetrics(service)(operation)(traceContext)
638638
.tflatMap(_ => {
639639
httpRateLimiter.withRateLimit(service)(operation).tflatMap { _ =>
640640
config.parameters.customTimeouts.get(operation) match {

apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/metrics/SvAppMetrics.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package org.lfdecentralizedtrust.splice.sv.metrics
55

66
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
7+
import com.digitalasset.canton.logging.NamedLoggerFactory
78
import org.lfdecentralizedtrust.splice.BaseSpliceMetrics
89
import com.digitalasset.canton.metrics.DbStorageHistograms
910

@@ -14,4 +15,5 @@ import com.digitalasset.canton.metrics.DbStorageHistograms
1415
class SvAppMetrics(
1516
metricsFactory: LabeledMetricsFactory,
1617
storageHistograms: DbStorageHistograms,
17-
) extends BaseSpliceMetrics("sv", metricsFactory, storageHistograms) {}
18+
loggerFactory: NamedLoggerFactory,
19+
) extends BaseSpliceMetrics("sv", metricsFactory, storageHistograms, loggerFactory) {}

apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/metrics/ValidatorAppMetrics.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package org.lfdecentralizedtrust.splice.validator.metrics
55

66
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
7+
import com.digitalasset.canton.logging.NamedLoggerFactory
78
import com.digitalasset.canton.metrics.DbStorageHistograms
89
import org.lfdecentralizedtrust.splice.BaseSpliceMetrics
910

@@ -12,4 +13,5 @@ import org.lfdecentralizedtrust.splice.BaseSpliceMetrics
1213
class ValidatorAppMetrics(
1314
metricsFactory: LabeledMetricsFactory,
1415
storageHistograms: DbStorageHistograms,
15-
) extends BaseSpliceMetrics("validator", metricsFactory, storageHistograms) {}
16+
loggerFactory: NamedLoggerFactory,
17+
) extends BaseSpliceMetrics("validator", metricsFactory, storageHistograms, loggerFactory) {}

0 commit comments

Comments
 (0)