function initMetrics()

in cloudrun-malware-scanner/metrics.ts [238:325]


function initMetrics(projectId: string) {
  if (!projectId) {
    throw Error('Unable to proceed without a Project ID');
  }

  logger.debug('initializing metrics');

  const resources = new GcpDetectorSync()
    .detect()
    .merge(new Resource(RESOURCE_ATTRIBUTES));

  const meterProvider = new MeterProvider({
    resource: resources,
    readers: [
      new PeriodicExportingMetricReader({
        exportIntervalMillis: METRIC_EXPORT_INTERVAL,
        exportTimeoutMillis: METRIC_EXPORT_INTERVAL,
        exporter: new GcpMetricExporter({prefix: 'workload.googleapis.com'}),
      }),
    ],
  });

  const meter = meterProvider.getMeter(COUNTERS_PREFIX);

  // Create cumulative counters
  [
    {
      name: COUNTER_NAMES.cleanFiles,
      description:
        'Number of files scanned that were found to be clean of malware at the time of scan',
    },
    {
      name: COUNTER_NAMES.ignoredFiles,
      description: 'Number of files that were ignored and not scanned',
    },
    {
      name: COUNTER_NAMES.infectedFiles,
      description:
        'Number of files scanned that were found to contain malware at the time of scan',
    },
    {
      name: COUNTER_NAMES.scansFailed,
      description: 'Number of malware scan requests which failed',
    },
    {
      name: COUNTER_NAMES.cvdUpdates,
      description:
        'Number of CVD mirror update checks performed with their status',
    },
    {
      name: COUNTER_NAMES.bytesScanned,
      description: 'Total number of bytes scanned',
      unit: 'By',
    },
  ].forEach((counter) =>
    COUNTERS.set(counter.name, {
      cumulative: meter.createCounter(COUNTERS_PREFIX + counter.name, {
        description: counter.description,
        unit: counter.unit,
      }),
    }),
  );

  COUNTERS.set(COUNTER_NAMES.scanDuration, {
    histogram: meter.createHistogram(
      COUNTERS_PREFIX + COUNTER_NAMES.scanDuration,
      {
        description: 'Duration spent scanning files',
        unit: 'ms',
        advice: {
          explicitBucketBoundaries: [
            0, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000,
            200000,
          ],
        },
      },
    ),
  });

  // Sanity check on COUNTERS length
  if (COUNTERS.size !== Object.keys(COUNTER_NAMES).length) {
    throw new Error('Code Error: not all counters initialized');
  }

  logger.info(
    `Metrics initialized for ${METRIC_TYPE_ROOT} on project ${projectId}`,
  );
}