Openflow telemetry

Openflow writes logs and metrics to the event table that you configured when you set up Openflow (BYOC | Snowflake deployment). This topic describes that telemetry and how to query it.

For setting up predefined alerts, see Set up alerts for Openflow.

For pre-built metrics visualization, see Monitor connectors using the Openflow Connectors Dashboard.

For metrics specific to a given connector type, see Connector-specific metrics.

For legacy runtime metrics, see Runtime metrics: Event table (deprecated) and Runtime metrics: Export (deprecated).

Metrics

Connector metrics

The following metrics are emitted every 60 seconds only for connectors that are running.

MetricDescription
connector.bytes.receivedBytes the connector received from external sources.
connector.bytes.sentBytes the connector sent to external destinations, such as Snowflake.
connector.time.processingTime, in nanoseconds, that all components of the connector spent processing data.

Connector metrics have the following attributes:

AttributeDescription
connector.idUnique identifier of the connector in Openflow.
connector.nameName of the connector.
connector.typeType of the connector.
connector.versionVersion of the connector.

Component metrics

The following metrics are emitted every 60 seconds only for processors that are running.

MetricDescription
component.bytes.sentBytes a processor sent to an external destination, such as Snowflake. Reported only for processors that sent data in a given reporting interval.

Component metrics have the following attributes:

AttributeDescription
component.idUnique identifier of the processor.
component.nameName of the processor.
component.typeType of the processor, for example PutSnowpipeStreaming.
process.group.id.pathSlash-delimited path of process group identifiers of the processor.
process.group.name.pathSlash-delimited path of process group names of the processor.
connector.idUnique identifier of the connector. Set only for components of connectors.
connector.nameName of the connector. Set only for components of connectors.
connector.typeType of the connector. Set only for components of connectors.
connector.versionVersion of the connector. Set only for components of connectors.

Connection metrics

The following metrics are emitted every 60 seconds only for connections for which FlowFiles entered or left the queue in a given reporting interval. If there was no activity on a given queue, no value is emitted.

MetricDescription
connection.flowfiles.queuedNumber of FlowFiles queued in the connection.
connection.bytes.queuedSize, in bytes, of the FlowFiles queued in the connection.
connection.backpressure.flowfiles.thresholdNumber of queued FlowFiles at which the connection applies back pressure.
connection.backpressure.bytes.thresholdSize, in bytes, of queued FlowFiles at which the connection applies back pressure.

Connection metrics have the following attributes:

AttributeDescription
component.idUnique identifier of the connection.
component.nameName of the connection.
component.typeThe fixed value Connection.
process.group.id.pathSlash-delimited path of process group identifiers of the connection.
process.group.name.pathSlash-delimited path of process group names of the connection.
connector.idUnique identifier of the connector. Set only for components of connectors.
connector.nameName of the connector. Set only for components of connectors.
connector.typeType of the connector. Set only for components of connectors.
connector.versionVersion of the connector. Set only for components of connectors.

Storage metrics

The following metrics are emitted every 60 seconds.

MetricDescription
storage.freeFree disk space, in bytes, on the disk that holds the repository.
storage.usedUsed disk space, in bytes, on the disk that holds the repository.

Storage metrics have the following attributes:

AttributeDescription
idIdentifier of the repository.
nameName of the repository.
storage.typeOne of: flowfile, content, provenance, or configuration_resources.

CPU metrics

The following metrics are emitted every 60 seconds.

MetricDescription
cores.availableNumber of processors available to the runtime node.
cores.loadSystem load average for the last minute, for example 3.2. -1 if the load average isn’t available.

CPU metrics have the following attributes:

AttributeDescription
idThe fixed value cpu.
nameName of the operating system.
architectureArchitecture of the operating system.
versionVersion of the operating system.

JVM metrics

The following metrics are emitted every 60 seconds.

MetricDescription
jvm.memory.heap.usedHeap memory used, in bytes.
jvm.memory.heap.committedHeap memory committed, in bytes.
jvm.memory.heap.maxMaximum heap memory, in bytes.
jvm.memory.heap.initInitial heap memory, in bytes.
jvm.memory.heap.usageHeap memory used divided by maximum heap memory, from 0 to 1. -1 if the maximum is undefined.
jvm.memory.non-heap.usageNon-heap memory used divided by maximum non-heap memory, from 0 to 1. -1 if the maximum is undefined.
jvm.memory.total.usedHeap and non-heap memory used, in bytes.
jvm.memory.total.committedHeap and non-heap memory committed, in bytes.
jvm.memory.total.maxMaximum heap and non-heap memory, in bytes.
jvm.memory.total.initInitial heap and non-heap memory, in bytes.
jvm.threads.countNumber of live threads.
jvm.threads.daemon.countNumber of live daemon threads.
jvm.threads.deadlocksNumber of deadlocked threads.
jvm.gc.<collector>.runsNumber of garbage collections since the JVM started, for each garbage collector. Spaces in the collector name are replaced with hyphens, for example jvm.gc.G1-Young-Generation.runs.
jvm.gc.<collector>.timeTime, in milliseconds, spent in garbage collection since the JVM started, for each garbage collector.

JVM metrics have the following attributes:

AttributeDescription
jvm.vendorVendor of the JVM.
jvm.versionVersion of the JVM.

Container metrics

The following metrics are emitted every 60 seconds.

MetricDescription
container.cpu.usageCPU used by the container, in cores.
container.memory.usageMemory used by the container, in bytes.
container.memory.availableMemory available to the container, in bytes.

For more information about container metrics, see the OpenTelemetry Kubelet Stats Receiver documentation.

Connector-specific metrics

Some connectors report custom metrics. For these metrics, see the monitoring page of the connector:

Metric resource attributes

All metrics, including connector-specific metrics, have the following resource attributes:

AttributeDescription
applicationThe fixed value openflow.
cloud.service.providerFor Snowflake deployments: snowflake. For BYOC AWS deployments: aws.
deployment.versionVersion of the deployment.
k8s.pod.uidUniquely identifies the runtime node that is emitting the metrics.
openflow.dataplane.idUnique identifier of the deployment, shown as ID in the deployment details in Openflow.
openflow.runtime.idUnique identifier of the runtime.
service.versionVersion of the runtime.

Container metrics are the exception. Their resource attributes include standard kubernetes attributes instead.

Logs

Log format

Openflow runtimes emit logs as JSON. To break the VALUE column into the following structured fields, apply TRY_PARSE_JSON to it:

NameTypeDescription
formattedMessageStringContents of the log message.
levelStringOne of: ERROR, WARN, INFO, DEBUG, or TRACE.
loggerNameStringThe fully qualified class name for the logger.
nanosecondsIntegerNanoseconds elapsed within the second in which this log message was created. Use it with timestamp for sub-millisecond precision.
threadNameStringName of the thread handling this call.
throwableJSON ObjectStack trace information for logs at ERROR level.
timestampIntegerTime that this log message was created, represented as milliseconds since the UNIX epoch.
mdcJSON ObjectAdditional context for the log entry. See Log context fields.

Log context fields

The mdc object contains the following fields. service.version and openflow.runtime.id are present on all runtime log entries. The other fields are present only for log entries produced by flow components, and only when they apply to that component.

FieldDescription
processGroupIdUnique identifier of the process group that contains the component.
processGroupNameName of the process group that contains the component.
processGroupIdPathSlash-delimited path of process group identifiers, starting at the root process group.
processGroupNamePathSlash-delimited path of process group names, starting at the root process group.
registeredFlowIdentifierIdentifier of the versioned flow that contains the component. Present for all versioned flows, including Openflow connectors.
registeredFlowVersionVersion of the versioned flow that contains the component.
registeredFlowIdentifierPathSlash-delimited path of the versioned flows that contain the component, starting at the root process group. Each versioned flow is shown as identifier:version.
snowOpenflowConnectorIdUnique identifier of the connector in Snowflake. Set only for gen 2 connectors.
connectorIdUnique identifier of the connector in Openflow.
connectorNameName of the connector.
connectorDefinitionIdType of the connector.
connectorBundleVersionVersion of the connector.
service.versionVersion of the Openflow runtime.
openflow.runtime.idUnique identifier of the Openflow runtime.

Log levels

Openflow processors (com.snowflake.openflow.runtime.processors.*) default to the WARN log level. To change the log level for a processor, update the bulletin level in the processor configuration on the canvas.

Log resource attributes

Logs have the following resource attributes:

AttributeDescription
applicationThe fixed value openflow.
cloud.service.providerOne of: snowflake or aws.
deployment.versionVersion of the deployment.
openflow.dataplane.idUnique identifier of the deployment.

Example queries

The following queries are examples to get you started with Openflow telemetry.

All queries assume that Openflow is configured to send telemetry to the default event table, SNOWFLAKE.TELEMETRY.EVENTS. If your account or Openflow deployment is configured with a different event table, substitute that table name where you see SNOWFLAKE.TELEMETRY.EVENTS.

For queries about connector-specific metrics, see Connector-specific metrics.

Find connections close to back pressure

SELECT
  resource_attributes:"openflow.dataplane.id" AS deployment_id,
  resource_attributes:"openflow.runtime.id" AS runtime_id,
  record_attributes:"connector.name" AS connector_name,
  record_attributes:"component.name" AS connection_name,
  record_attributes:"component.id" AS connection_id,
  MAX(IFF(record:metric:name = 'connection.flowfiles.queued', value::NUMBER, NULL)) AS flowfiles_queued,
  MAX(IFF(record:metric:name = 'connection.backpressure.flowfiles.threshold', value::NUMBER, NULL)) AS flowfiles_threshold,
  MAX(IFF(record:metric:name = 'connection.bytes.queued', value::NUMBER, NULL)) AS bytes_queued,
  MAX(IFF(record:metric:name = 'connection.backpressure.bytes.threshold', value::NUMBER, NULL)) AS bytes_threshold
FROM snowflake.telemetry.events
WHERE true
  AND timestamp > DATEADD(minute, -10, SYSDATE())
  AND record_type = 'METRIC'
  AND record:metric:name IN (
    'connection.flowfiles.queued',
    'connection.backpressure.flowfiles.threshold',
    'connection.bytes.queued',
    'connection.backpressure.bytes.threshold')
GROUP BY 1, 2, 3, 4, 5
HAVING flowfiles_queued >= 0.8 * flowfiles_threshold
  OR bytes_queued >= 0.8 * bytes_threshold
ORDER BY flowfiles_queued DESC;

Find error logs for Openflow runtimes

SELECT
  timestamp,
  resource_attributes:"openflow.dataplane.id" AS deployment_id,
  TRY_PARSE_JSON(value):mdc:"openflow.runtime.id" AS runtime_id,
  TRY_PARSE_JSON(value):loggerName AS logger,
  TRY_PARSE_JSON(value):formattedMessage AS message,
  TRY_PARSE_JSON(value) AS parsed_log
FROM snowflake.telemetry.events
WHERE true
  AND timestamp > DATEADD(minute, -30, SYSDATE())
  AND record_type = 'LOG'
  AND record:severity_text = 'ERROR'
  AND runtime_id IS NOT NULL
ORDER BY timestamp DESC;

Find the amount of data ingested by each connector

SELECT
  DATE_TRUNC('hour', timestamp) AS hour,
  resource_attributes:"openflow.runtime.id" AS runtime_id,
  record_attributes:"connector.name" AS connector_name,
  SUM(value::NUMBER) AS bytes_sent
FROM snowflake.telemetry.events
WHERE true
  AND timestamp > DATEADD(day, -1, SYSDATE())
  AND record_type = 'METRIC'
  AND record:metric:name = 'connector.bytes.sent'
GROUP BY 1, 2, 3
ORDER BY 1 DESC, bytes_sent DESC;

Find high JVM heap usage for Openflow runtimes

SELECT
  resource_attributes:"openflow.dataplane.id" AS deployment_id,
  resource_attributes:"openflow.runtime.id" AS runtime_id,
  resource_attributes:"k8s.pod.uid" AS node_id,
  MAX(value::FLOAT) * 100 AS max_heap_usage_percentage
FROM snowflake.telemetry.events
WHERE true
  AND timestamp > DATEADD(minute, -30, SYSDATE())
  AND record_type = 'METRIC'
  AND record:metric:name = 'jvm.memory.heap.usage'
GROUP BY 1, 2, 3
HAVING max_heap_usage_percentage > 85
ORDER BY max_heap_usage_percentage DESC;

Find high CPU usage for Openflow runtimes

SELECT
  DATE_TRUNC('minute', timestamp) AS minute,
  resource_attributes:"openflow.dataplane.id" AS deployment_id,
  resource_attributes:"openflow.runtime.id" AS runtime_id,
  resource_attributes:"k8s.pod.uid" AS node_id,
  MAX(IFF(record:metric:name = 'cores.load', value::FLOAT, NULL)) AS max_load,
  MAX(IFF(record:metric:name = 'cores.available', value::NUMBER, NULL)) AS cores_available,
  max_load / cores_available * 100 AS load_percentage
FROM snowflake.telemetry.events
WHERE true
  AND timestamp > DATEADD(minute, -30, SYSDATE())
  AND record_type = 'METRIC'
  AND record:metric:name IN ('cores.load', 'cores.available')
  AND value::FLOAT >= 0
GROUP BY 1, 2, 3, 4
ORDER BY minute DESC, load_percentage DESC;