Skip to content

Commit cadb4ce

Browse files
authored
fix: track published bytecode (#10636)
Tracks public bytecode emitted by private only TX and also adds explicit buckets for the bytecode size histogram. I've also defined global histogram buckets for histograms tracking durations (`ms` unit) and histograms tracking sizes (`By` - bytes - unit). This way we can be sure that all histograms use appropriately sized buckets instead of using the Otel defaults.
1 parent b2c4f48 commit cadb4ce

File tree

14 files changed

+58
-120
lines changed

14 files changed

+58
-120
lines changed

yarn-project/archiver/src/archiver/instrumentation.ts

-8
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import {
1010
type TelemetryClient,
1111
type UpDownCounter,
1212
ValueType,
13-
exponentialBuckets,
14-
millisecondBuckets,
1513
} from '@aztec/telemetry-client';
1614

1715
export class ArchiverInstrumentation {
@@ -41,9 +39,6 @@ export class ArchiverInstrumentation {
4139
unit: 'ms',
4240
description: 'Duration to sync a block',
4341
valueType: ValueType.INT,
44-
advice: {
45-
explicitBucketBoundaries: exponentialBuckets(1, 16),
46-
},
4742
});
4843

4944
this.proofsSubmittedCount = meter.createUpDownCounter(Metrics.ARCHIVER_ROLLUP_PROOF_COUNT, {
@@ -55,9 +50,6 @@ export class ArchiverInstrumentation {
5550
unit: 'ms',
5651
description: 'Time after a block is submitted until its proof is published',
5752
valueType: ValueType.INT,
58-
advice: {
59-
explicitBucketBoundaries: millisecondBuckets(1, 80), // 10ms -> ~3hs
60-
},
6153
});
6254

6355
this.l1BlocksSynced = meter.createUpDownCounter(Metrics.ARCHIVER_L1_BLOCKS_SYNCED, {

yarn-project/aztec-node/src/aztec-node/node_metrics.ts

-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ export class NodeMetrics {
1818
description: 'The duration of the receiveTx method',
1919
unit: 'ms',
2020
valueType: ValueType.INT,
21-
advice: {
22-
explicitBucketBoundaries: [10, 50, 100, 200, 500, 1000, 2000, 5000],
23-
},
2421
});
2522
}
2623

yarn-project/bb-prover/src/instrumentation.ts

-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
type TelemetryClient,
99
type Tracer,
1010
ValueType,
11-
millisecondBuckets,
1211
} from '@aztec/telemetry-client';
1312

1413
/**
@@ -36,27 +35,18 @@ export class ProverInstrumentation {
3635
description: 'Records how long it takes to simulate a circuit',
3736
unit: 'ms',
3837
valueType: ValueType.INT,
39-
advice: {
40-
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
41-
},
4238
});
4339

4440
this.witGenDuration = meter.createHistogram(Metrics.CIRCUIT_WITNESS_GEN_DURATION, {
4541
description: 'Records how long it takes to generate the partial witness for a circuit',
4642
unit: 'ms',
4743
valueType: ValueType.INT,
48-
advice: {
49-
explicitBucketBoundaries: millisecondBuckets(1),
50-
},
5144
});
5245

5346
this.provingDuration = meter.createHistogram(Metrics.CIRCUIT_PROVING_DURATION, {
5447
unit: 'ms',
5548
description: 'Records how long it takes to prove a circuit',
5649
valueType: ValueType.INT,
57-
advice: {
58-
explicitBucketBoundaries: millisecondBuckets(2), // 100ms -> 54 minutes
59-
},
6050
});
6151

6252
this.witGenInputSize = meter.createGauge(Metrics.CIRCUIT_WITNESS_GEN_INPUT_SIZE, {

yarn-project/p2p/src/mem_pools/instrumentation.ts

-11
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,6 @@ export class PoolInstrumentation<PoolObject extends Gossipable> {
7272
this.objectSize = meter.createHistogram(metricsLabels.objectSize, {
7373
unit: 'By',
7474
description: 'The size of transactions in the mempool',
75-
advice: {
76-
explicitBucketBoundaries: [
77-
5_000, // 5KB
78-
10_000,
79-
20_000,
80-
50_000,
81-
75_000,
82-
100_000, // 100KB
83-
200_000,
84-
],
85-
},
8675
});
8776

8877
this.dbMetrics = new LmdbMetrics(

yarn-project/prover-client/src/orchestrator/orchestrator_metrics.ts

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
type Histogram,
3-
Metrics,
4-
type TelemetryClient,
5-
type Tracer,
6-
ValueType,
7-
millisecondBuckets,
8-
} from '@aztec/telemetry-client';
1+
import { type Histogram, Metrics, type TelemetryClient, type Tracer, ValueType } from '@aztec/telemetry-client';
92

103
export class ProvingOrchestratorMetrics {
114
public readonly tracer: Tracer;
@@ -20,9 +13,6 @@ export class ProvingOrchestratorMetrics {
2013
unit: 'ms',
2114
description: 'Duration to build base rollup inputs',
2215
valueType: ValueType.INT,
23-
advice: {
24-
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
25-
},
2616
});
2717
}
2818

yarn-project/prover-client/src/proving_broker/proving_broker_instrumentation.ts

-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
type TelemetryClient,
1010
type UpDownCounter,
1111
ValueType,
12-
millisecondBuckets,
1312
} from '@aztec/telemetry-client';
1413

1514
export type MonitorCallback = (proofType: ProvingRequestType) => number;
@@ -55,18 +54,12 @@ export class ProvingBrokerInstrumentation {
5554
description: 'Records how long a job sits in the queue',
5655
unit: 'ms',
5756
valueType: ValueType.INT,
58-
advice: {
59-
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
60-
},
6157
});
6258

6359
this.jobDuration = meter.createHistogram(Metrics.PROVING_QUEUE_JOB_DURATION, {
6460
description: 'Records how long a job takes to complete',
6561
unit: 'ms',
6662
valueType: ValueType.INT,
67-
advice: {
68-
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
69-
},
7063
});
7164
}
7265

yarn-project/prover-node/src/metrics.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type Timer } from '@aztec/foundation/timer';
2-
import { type Histogram, Metrics, type TelemetryClient, ValueType, millisecondBuckets } from '@aztec/telemetry-client';
2+
import { type Histogram, Metrics, type TelemetryClient, ValueType } from '@aztec/telemetry-client';
33

44
export class ProverNodeMetrics {
55
provingJobDuration: Histogram;
@@ -10,9 +10,6 @@ export class ProverNodeMetrics {
1010
description: 'Duration of proving job',
1111
unit: 'ms',
1212
valueType: ValueType.INT,
13-
advice: {
14-
explicitBucketBoundaries: millisecondBuckets(2), // 60 buckets spanning an interval of ~100ms to ~1hour
15-
},
1613
});
1714
}
1815

yarn-project/sequencer-client/src/publisher/l1-publisher-metrics.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ export class L1PublisherMetrics {
3838
description: 'The duration of transaction processing',
3939
unit: 'ms',
4040
valueType: ValueType.INT,
41-
advice: {
42-
explicitBucketBoundaries: [10, 50, 100, 200, 500, 1000, 2000, 5000, 10000],
43-
},
4441
});
4542

4643
this.txGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS, {
@@ -51,11 +48,8 @@ export class L1PublisherMetrics {
5148

5249
this.txCalldataSize = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
5350
description: 'The size of the calldata in transactions',
54-
unit: 'bytes',
51+
unit: 'By',
5552
valueType: ValueType.INT,
56-
advice: {
57-
explicitBucketBoundaries: [0, 100, 200, 500, 1000, 2000, 5000, 10000],
58-
},
5953
});
6054

6155
this.txCalldataGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {

yarn-project/sequencer-client/src/sequencer/metrics.ts

-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
type Tracer,
88
type UpDownCounter,
99
ValueType,
10-
millisecondBuckets,
1110
} from '@aztec/telemetry-client';
1211

1312
import { type SequencerState, type SequencerStateCallback, sequencerStateToNumber } from './utils.js';
@@ -32,18 +31,12 @@ export class SequencerMetrics {
3231
unit: 'ms',
3332
description: 'Duration to build a block',
3433
valueType: ValueType.INT,
35-
advice: {
36-
explicitBucketBoundaries: millisecondBuckets(2),
37-
},
3834
});
3935
this.stateTransitionBufferDuration = meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION, {
4036
unit: 'ms',
4137
description:
4238
'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
4339
valueType: ValueType.INT,
44-
advice: {
45-
explicitBucketBoundaries: millisecondBuckets(2),
46-
},
4740
});
4841

4942
const currentState = meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {

yarn-project/simulator/src/public/executor_metrics.ts

-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
type Tracer,
77
type UpDownCounter,
88
ValueType,
9-
linearBuckets,
109
} from '@aztec/telemetry-client';
1110

1211
export class ExecutorMetrics {
@@ -33,9 +32,6 @@ export class ExecutorMetrics {
3332
description: 'Mana used per second',
3433
unit: 'mana/s',
3534
valueType: ValueType.INT,
36-
advice: {
37-
explicitBucketBoundaries: linearBuckets(0, 10_000_000, 10),
38-
},
3935
});
4036
}
4137

yarn-project/simulator/src/public/public_processor.ts

+7
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,13 @@ export class PublicProcessor {
253253
feePaymentPublicDataWrite,
254254
this.globalVariables,
255255
);
256+
257+
this.metrics.recordClassRegistration(
258+
...tx.contractClassLogs
259+
.unrollLogs()
260+
.filter(log => ContractClassRegisteredEvent.isContractClassRegisteredEvent(log.data))
261+
.map(log => ContractClassRegisteredEvent.fromLog(log.data)),
262+
);
256263
return [processedTx];
257264
}
258265

Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { exponentialBuckets, linearBuckets, millisecondBuckets } from './histogram_utils.js';
1+
import { exponentialBuckets, linearBuckets } from './histogram_utils.js';
22

33
describe('linearBuckets', () => {
44
it.each([[10, 1_000, 5, [10, 208, 406, 604, 802, 1000]]] as const)(
@@ -17,31 +17,3 @@ describe('exponentialBuckets', () => {
1717
},
1818
);
1919
});
20-
21-
describe('millisecondBuckets', () => {
22-
it('should throw an error if significantFractionalDigits is less than 1', () => {
23-
expect(() => millisecondBuckets(0)).toThrow();
24-
});
25-
26-
it('should return the expected buckets for milliseconds', () => {
27-
expect(millisecondBuckets(1, 16)).toEqual([
28-
10, // 2^0 * 10
29-
12,
30-
14,
31-
17,
32-
20, // 2^1 * 10
33-
24,
34-
28,
35-
34,
36-
40, // 2^2 * 10
37-
48,
38-
57,
39-
67,
40-
80, // 2^3 * 10
41-
95,
42-
113,
43-
135,
44-
160, // 2^4 * 10
45-
]);
46-
});
47-
});

yarn-project/telemetry-client/src/histogram_utils.ts

+2-18
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
* @returns - An array of bucket boundaries
77
*/
88
export function linearBuckets(start: number, end: number, count: number): number[] {
9-
const buckets = [];
9+
const buckets: number[] = [];
1010
const step = (end - start) / count;
1111
for (let i = 0; i <= count; i++) {
12-
buckets.push(start + i * step);
12+
buckets.push(Math.floor(start + i * step));
1313
}
1414
return buckets;
1515
}
@@ -48,19 +48,3 @@ export function exponentialBuckets(scale: number, count: number): number[] {
4848
}
4949
return buckets;
5050
}
51-
52-
/**
53-
* Creates an array of exponential buckets optimized for milliseconds
54-
* @param significantFractionalDigits - The number of significant digits to round to
55-
* @param count - The number of buckets. Defaults to 60
56-
* @returns - An array of bucket boundaries
57-
*/
58-
export function millisecondBuckets(significantFractionalDigits: number, count = 60): number[] {
59-
if (significantFractionalDigits < 1) {
60-
// if significant digits is 1 then we end up having duplicate buckets
61-
throw new Error('significantFractionalDigits must be >= 1');
62-
}
63-
64-
const scale = 10 ** significantFractionalDigits;
65-
return exponentialBuckets(2, count).map(x => Math.round(x * scale));
66-
}

yarn-project/telemetry-client/src/otel.ts

+45-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
1616
import { HostMetrics } from '@opentelemetry/host-metrics';
1717
import { type IResource } from '@opentelemetry/resources';
1818
import { type LoggerProvider } from '@opentelemetry/sdk-logs';
19-
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
19+
import {
20+
ExplicitBucketHistogramAggregation,
21+
InstrumentType,
22+
MeterProvider,
23+
PeriodicExportingMetricReader,
24+
View,
25+
} from '@opentelemetry/sdk-metrics';
2026
import { BatchSpanProcessor, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
2127
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
2228

2329
import { type TelemetryClientConfig } from './config.js';
30+
import { linearBuckets } from './histogram_utils.js';
2431
import { registerOtelLoggerProvider } from './otel_logger_provider.js';
2532
import { getOtelResource } from './otel_resource.js';
2633
import { type Gauge, type TelemetryClient } from './telemetry.js';
@@ -140,6 +147,43 @@ export class OpenTelemetryClient implements TelemetryClient {
140147
exportTimeoutMillis: config.otelExportTimeoutMs,
141148
}),
142149
],
150+
views: [
151+
// Every histogram matching the selector (type + unit) gets these custom buckets assigned
152+
new View({
153+
instrumentType: InstrumentType.HISTOGRAM,
154+
instrumentUnit: 'ms',
155+
aggregation: new ExplicitBucketHistogramAggregation(
156+
// 181 buckets between 5ms and 1hr
157+
[
158+
...linearBuckets(5, 100, 20), // 20 buckets between 5 and 100ms
159+
...linearBuckets(100, 1_000, 20).slice(1), // another 20 buckets between 100ms and 1s. slice(1) to remove duplicate 100
160+
...linearBuckets(1_000, 10_000, 20).slice(1),
161+
...linearBuckets(10_000, 60_000, 20).slice(1),
162+
...linearBuckets(60_000, 300_000, 20).slice(1),
163+
...linearBuckets(300_000, 600_000, 20).slice(1),
164+
...linearBuckets(600_000, 1_200_000, 20).slice(1),
165+
...linearBuckets(1_200_000, 1_800_000, 20).slice(1),
166+
...linearBuckets(1_800_000, 3_600_000, 20).slice(1), // 1hr
167+
],
168+
true,
169+
),
170+
}),
171+
new View({
172+
instrumentType: InstrumentType.HISTOGRAM,
173+
instrumentUnit: 'By',
174+
aggregation: new ExplicitBucketHistogramAggregation(
175+
// 143 buckets between 32 bytes and 2MB
176+
[
177+
...linearBuckets(2 ** 5, 2 ** 10, 31), // 32 bytes to 1KB at a resolution of 32 bytes
178+
...linearBuckets(2 ** 10, 2 ** 15, 31).slice(1), // 1KB to 32KB at a resolution of 1KB
179+
...linearBuckets(2 ** 15, 2 ** 18, 32).slice(1), // 32KB to 256KB at a resolution of 7KB
180+
...linearBuckets(2 ** 18, 2 ** 20, 32).slice(1), // 256KB to 1MB at a resolution of 24KB
181+
...linearBuckets(2 ** 20, 2 ** 21, 16).slice(1), // 1MB to 2MB at a resolution of 64KB
182+
],
183+
true,
184+
),
185+
}),
186+
],
143187
});
144188

145189
const loggerProvider = await registerOtelLoggerProvider(resource, config.logsCollectorUrl);

0 commit comments

Comments
 (0)