Skip to content

Commit

Permalink
fix: track published bytecode (#10636)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alexghr authored Dec 12, 2024
1 parent b2c4f48 commit cadb4ce
Show file tree
Hide file tree
Showing 14 changed files with 58 additions and 120 deletions.
8 changes: 0 additions & 8 deletions yarn-project/archiver/src/archiver/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
type TelemetryClient,
type UpDownCounter,
ValueType,
exponentialBuckets,
millisecondBuckets,
} from '@aztec/telemetry-client';

export class ArchiverInstrumentation {
Expand Down Expand Up @@ -41,9 +39,6 @@ export class ArchiverInstrumentation {
unit: 'ms',
description: 'Duration to sync a block',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: exponentialBuckets(1, 16),
},
});

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

this.l1BlocksSynced = meter.createUpDownCounter(Metrics.ARCHIVER_L1_BLOCKS_SYNCED, {
Expand Down
3 changes: 0 additions & 3 deletions yarn-project/aztec-node/src/aztec-node/node_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ export class NodeMetrics {
description: 'The duration of the receiveTx method',
unit: 'ms',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: [10, 50, 100, 200, 500, 1000, 2000, 5000],
},
});
}

Expand Down
10 changes: 0 additions & 10 deletions yarn-project/bb-prover/src/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
type TelemetryClient,
type Tracer,
ValueType,
millisecondBuckets,
} from '@aztec/telemetry-client';

/**
Expand Down Expand Up @@ -36,27 +35,18 @@ export class ProverInstrumentation {
description: 'Records how long it takes to simulate a circuit',
unit: 'ms',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
},
});

this.witGenDuration = meter.createHistogram(Metrics.CIRCUIT_WITNESS_GEN_DURATION, {
description: 'Records how long it takes to generate the partial witness for a circuit',
unit: 'ms',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(1),
},
});

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

this.witGenInputSize = meter.createGauge(Metrics.CIRCUIT_WITNESS_GEN_INPUT_SIZE, {
Expand Down
11 changes: 0 additions & 11 deletions yarn-project/p2p/src/mem_pools/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,6 @@ export class PoolInstrumentation<PoolObject extends Gossipable> {
this.objectSize = meter.createHistogram(metricsLabels.objectSize, {
unit: 'By',
description: 'The size of transactions in the mempool',
advice: {
explicitBucketBoundaries: [
5_000, // 5KB
10_000,
20_000,
50_000,
75_000,
100_000, // 100KB
200_000,
],
},
});

this.dbMetrics = new LmdbMetrics(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
type Histogram,
Metrics,
type TelemetryClient,
type Tracer,
ValueType,
millisecondBuckets,
} from '@aztec/telemetry-client';
import { type Histogram, Metrics, type TelemetryClient, type Tracer, ValueType } from '@aztec/telemetry-client';

export class ProvingOrchestratorMetrics {
public readonly tracer: Tracer;
Expand All @@ -20,9 +13,6 @@ export class ProvingOrchestratorMetrics {
unit: 'ms',
description: 'Duration to build base rollup inputs',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
},
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
type TelemetryClient,
type UpDownCounter,
ValueType,
millisecondBuckets,
} from '@aztec/telemetry-client';

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

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

Expand Down
5 changes: 1 addition & 4 deletions yarn-project/prover-node/src/metrics.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type Timer } from '@aztec/foundation/timer';
import { type Histogram, Metrics, type TelemetryClient, ValueType, millisecondBuckets } from '@aztec/telemetry-client';
import { type Histogram, Metrics, type TelemetryClient, ValueType } from '@aztec/telemetry-client';

export class ProverNodeMetrics {
provingJobDuration: Histogram;
Expand All @@ -10,9 +10,6 @@ export class ProverNodeMetrics {
description: 'Duration of proving job',
unit: 'ms',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(2), // 60 buckets spanning an interval of ~100ms to ~1hour
},
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ export class L1PublisherMetrics {
description: 'The duration of transaction processing',
unit: 'ms',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: [10, 50, 100, 200, 500, 1000, 2000, 5000, 10000],
},
});

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

this.txCalldataSize = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
description: 'The size of the calldata in transactions',
unit: 'bytes',
unit: 'By',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: [0, 100, 200, 500, 1000, 2000, 5000, 10000],
},
});

this.txCalldataGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {
Expand Down
7 changes: 0 additions & 7 deletions yarn-project/sequencer-client/src/sequencer/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
type Tracer,
type UpDownCounter,
ValueType,
millisecondBuckets,
} from '@aztec/telemetry-client';

import { type SequencerState, type SequencerStateCallback, sequencerStateToNumber } from './utils.js';
Expand All @@ -32,18 +31,12 @@ export class SequencerMetrics {
unit: 'ms',
description: 'Duration to build a block',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(2),
},
});
this.stateTransitionBufferDuration = meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION, {
unit: 'ms',
description:
'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(2),
},
});

const currentState = meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
Expand Down
4 changes: 0 additions & 4 deletions yarn-project/simulator/src/public/executor_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
type Tracer,
type UpDownCounter,
ValueType,
linearBuckets,
} from '@aztec/telemetry-client';

export class ExecutorMetrics {
Expand All @@ -33,9 +32,6 @@ export class ExecutorMetrics {
description: 'Mana used per second',
unit: 'mana/s',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: linearBuckets(0, 10_000_000, 10),
},
});
}

Expand Down
7 changes: 7 additions & 0 deletions yarn-project/simulator/src/public/public_processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,13 @@ export class PublicProcessor {
feePaymentPublicDataWrite,
this.globalVariables,
);

this.metrics.recordClassRegistration(
...tx.contractClassLogs
.unrollLogs()
.filter(log => ContractClassRegisteredEvent.isContractClassRegisteredEvent(log.data))
.map(log => ContractClassRegisteredEvent.fromLog(log.data)),
);
return [processedTx];
}

Expand Down
30 changes: 1 addition & 29 deletions yarn-project/telemetry-client/src/histogram_utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { exponentialBuckets, linearBuckets, millisecondBuckets } from './histogram_utils.js';
import { exponentialBuckets, linearBuckets } from './histogram_utils.js';

describe('linearBuckets', () => {
it.each([[10, 1_000, 5, [10, 208, 406, 604, 802, 1000]]] as const)(
Expand All @@ -17,31 +17,3 @@ describe('exponentialBuckets', () => {
},
);
});

describe('millisecondBuckets', () => {
it('should throw an error if significantFractionalDigits is less than 1', () => {
expect(() => millisecondBuckets(0)).toThrow();
});

it('should return the expected buckets for milliseconds', () => {
expect(millisecondBuckets(1, 16)).toEqual([
10, // 2^0 * 10
12,
14,
17,
20, // 2^1 * 10
24,
28,
34,
40, // 2^2 * 10
48,
57,
67,
80, // 2^3 * 10
95,
113,
135,
160, // 2^4 * 10
]);
});
});
20 changes: 2 additions & 18 deletions yarn-project/telemetry-client/src/histogram_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
* @returns - An array of bucket boundaries
*/
export function linearBuckets(start: number, end: number, count: number): number[] {
const buckets = [];
const buckets: number[] = [];
const step = (end - start) / count;
for (let i = 0; i <= count; i++) {
buckets.push(start + i * step);
buckets.push(Math.floor(start + i * step));
}
return buckets;
}
Expand Down Expand Up @@ -48,19 +48,3 @@ export function exponentialBuckets(scale: number, count: number): number[] {
}
return buckets;
}

/**
* Creates an array of exponential buckets optimized for milliseconds
* @param significantFractionalDigits - The number of significant digits to round to
* @param count - The number of buckets. Defaults to 60
* @returns - An array of bucket boundaries
*/
export function millisecondBuckets(significantFractionalDigits: number, count = 60): number[] {
if (significantFractionalDigits < 1) {
// if significant digits is 1 then we end up having duplicate buckets
throw new Error('significantFractionalDigits must be >= 1');
}

const scale = 10 ** significantFractionalDigits;
return exponentialBuckets(2, count).map(x => Math.round(x * scale));
}
46 changes: 45 additions & 1 deletion yarn-project/telemetry-client/src/otel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { HostMetrics } from '@opentelemetry/host-metrics';
import { type IResource } from '@opentelemetry/resources';
import { type LoggerProvider } from '@opentelemetry/sdk-logs';
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import {
ExplicitBucketHistogramAggregation,
InstrumentType,
MeterProvider,
PeriodicExportingMetricReader,
View,
} from '@opentelemetry/sdk-metrics';
import { BatchSpanProcessor, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';

import { type TelemetryClientConfig } from './config.js';
import { linearBuckets } from './histogram_utils.js';
import { registerOtelLoggerProvider } from './otel_logger_provider.js';
import { getOtelResource } from './otel_resource.js';
import { type Gauge, type TelemetryClient } from './telemetry.js';
Expand Down Expand Up @@ -140,6 +147,43 @@ export class OpenTelemetryClient implements TelemetryClient {
exportTimeoutMillis: config.otelExportTimeoutMs,
}),
],
views: [
// Every histogram matching the selector (type + unit) gets these custom buckets assigned
new View({
instrumentType: InstrumentType.HISTOGRAM,
instrumentUnit: 'ms',
aggregation: new ExplicitBucketHistogramAggregation(
// 181 buckets between 5ms and 1hr
[
...linearBuckets(5, 100, 20), // 20 buckets between 5 and 100ms
...linearBuckets(100, 1_000, 20).slice(1), // another 20 buckets between 100ms and 1s. slice(1) to remove duplicate 100
...linearBuckets(1_000, 10_000, 20).slice(1),
...linearBuckets(10_000, 60_000, 20).slice(1),
...linearBuckets(60_000, 300_000, 20).slice(1),
...linearBuckets(300_000, 600_000, 20).slice(1),
...linearBuckets(600_000, 1_200_000, 20).slice(1),
...linearBuckets(1_200_000, 1_800_000, 20).slice(1),
...linearBuckets(1_800_000, 3_600_000, 20).slice(1), // 1hr
],
true,
),
}),
new View({
instrumentType: InstrumentType.HISTOGRAM,
instrumentUnit: 'By',
aggregation: new ExplicitBucketHistogramAggregation(
// 143 buckets between 32 bytes and 2MB
[
...linearBuckets(2 ** 5, 2 ** 10, 31), // 32 bytes to 1KB at a resolution of 32 bytes
...linearBuckets(2 ** 10, 2 ** 15, 31).slice(1), // 1KB to 32KB at a resolution of 1KB
...linearBuckets(2 ** 15, 2 ** 18, 32).slice(1), // 32KB to 256KB at a resolution of 7KB
...linearBuckets(2 ** 18, 2 ** 20, 32).slice(1), // 256KB to 1MB at a resolution of 24KB
...linearBuckets(2 ** 20, 2 ** 21, 16).slice(1), // 1MB to 2MB at a resolution of 64KB
],
true,
),
}),
],
});

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

0 comments on commit cadb4ce

Please sign in to comment.