Azure Blob via Storage queue

Reads each blob Event Grid announces on a Storage queue, splits it into records, and deletes the message once Smeltr delivers every record.

The source receives a storage account's Event Grid BlobCreated events from a Storage queue and reads the blobs they name.

Example

Reads each announced blob one line per record, as the worker host's managed identity.

{
  "id": "blob-logs",
  "type": "azureBlobQueue",
  "queueUrl": "https://acmelogs.queue.core.windows.net/blob-events",
  "account": "acmelogs",
  "framing": "lines"
}
The Azure Blob via Storage queue form on the Sources page: id blob-logs, its queue URL, account acmelogs, framing lines.
Open complete screenshot ↗
The Azure Blob via Storage queue form on the Sources page: id blob-logs, its queue URL, account acmelogs, framing lines.
Open complete screenshot ↗
The same source on the Sources page.

Before you start

Settings

It also takes the settings every source takes.

queueUrl string required

The URL of the Storage queue Event Grid sends BlobCreated events to. Its name is at most 56 characters, leaving room for its poison queue's -poison.

Examples
https://acmelogs.queue.core.windows.net/blob-eventshttp://127.0.0.1:10001/acmelogs/blob-events

account string required

The storage account holding the blobs. A blob in another account is refused.

Example
acmelogs

accessKey credential default none

The credential holding the account's access key. Set at most one of accessKey, sasToken, clientSecret and managedIdentityClientId; with none, the host's managed or workload identity is used.

Examples
AZURE_ACCESS_KEY{"secret": "azure-access-key","version": 1}

sasToken credential default none

The credential holding an account shared access signature that covers both the blob and queue services.

Examples
AZURE_SAS_TOKEN{"secret": "azure-sas-token","version": 1}

tenantId string default none

A service principal's tenant. Set tenantId, clientId and clientSecret together, or none of them.

Example
00000000-0000-0000-0000-000000000000

clientId string default none

A service principal's client id.

Example
11111111-1111-1111-1111-111111111111

clientSecret credential default none

The credential holding a service principal's client secret.

Examples
AZURE_CLIENT_SECRET{"secret": "azure-client-secret","version": 1}

managedIdentityClientId string default the host's managed or workload identity

The client id of the user-assigned managed identity to sign in as. Set it when the worker's host has more than one managed identity. Left out, it signs in as the host's managed identity, or an AKS pod's workload identity.

Example
22222222-2222-2222-2222-222222222222

format string default each payload is text, in _raw

How each payload becomes the record.

avro
Reads Avro files. Fields you don't declare are kept.

fields list of fields default none

The Avro fields to read, each with a name and a type such as i64 or str. Name a nested field with dots, such as user.id. Top-level fields you don't list are kept. Only with format avro.

Example
[{"name": "user_id","type": "i64"},{"name": "user.name","type": "str"}]

framing string default lines

How an object becomes records.

lines
Gives one record per line, or per piece lineBreaker cuts.
object
Gives the whole object as one record, for a JSON document such as CloudTrail's that a pipeline unrolls.
escapedLines
Gives one record per line, unescaped as a bytes object destination wrote it.

lineBreaker string default a record per line

With lines framing, and only then: where a record ends. Its first capture group is the break and is dropped: the bytes before it end a record, line ends and all, and the bytes after it start the next. What follows the group is kept, so the pattern can say how a record starts: ([\r\n]+)\d{4}- keeps a stack trace with the line that logged it, and </event>(\s*) cuts XML events with no line ends between them. It needs a capture group and must not match the empty string.

Examples
([\r\n]+)\d{4}-</event>(\s*)

identity identity default none

The connection identity it connects under, for a private CA or a client certificate.

Examples
azure-proxycorp-proxy

Advanced

endpoint string default the account's, in Azure's public cloud

The blob service's address, such as Azurite's or a sovereign cloud's.

Examples
http://localhost:10000/acmelogshttps://acmelogs.blob.core.usgovcloudapi.net

authEndpoint string default its cloud's own

Where a client secret is exchanged for a token. Only with clientSecret.

Examples
https://login.microsoftonline.ushttps://login.chinacloudapi.cn

encoding string default auto

How a record's bytes become _raw's text: auto, none, or a WHATWG encoding label other than the replacement ones, such as utf-8, utf-16le or shift_jis.

auto
Detects each record's encoding.
utf-8
Decodes every record as UTF-8, as any other label decodes as its own encoding. Bytes that do not decode become U+FFFD.
none
Decodes nothing: the record has no _raw, and its payload is __source.bytes alone. A pipeline reads it as text with decode(__source.bytes, encoding).

visibilitySecs integer default 60

Seconds a received message stays hidden from other readers. The source extends it while it reads the message's blobs. 1 to 43200.

Examples
3003043200

maxDeliveries integer default 5

Times a message is received before it is moved to the queue named after this one with -poison added. 1 to 1000.

Examples
103100

Fields it gives

__source.bucket holds the blob's container, and __source.key its name.

FieldTypeHolds
__source.namestrThe name of the source that read the record.
__source.typestrThe kind of source that read it, its type, such as kafka, s3List, httpApi or hecReceiver.
__source.bucketstrThe bucket, or Azure container, the record's object is in.
__source.keystrThe key, or Azure blob name, of the object the record was read from.
__source.offseti64The record's offset in its Kafka or Event Hubs partition, or its record number in its object, from 0.
__source.bytesbytesThe record's payload as the source read it, before any decoding. The source decodes _raw from it. A bytes destination writes it unless the destination names another field. Text functions refuse it; decode(__source.bytes, encoding) reads it as text.

How it works

A message may hold one event or an array of them, as plain text or base64. The source reads the blob a BlobCreated event names, at its latest version. For a Data Lake file it skips CreateFile and reads the file at FlushWithClose. The source deletes a message that announces no blob without reading anything. A message that is not an Event Grid event, or names a blob in another account, stays on the queue, like one whose blob the source cannot read.

The source decompresses a gzip, zstd, framed snappy or framed lz4 blob first and reads any other as it is.

The source keeps a message hidden while it reads the message's blobs and Smeltr delivers them, and deletes it once Smeltr commits every record of every blob it names. It never deletes a message whose blob it cannot read, and moves a message received more than maxDeliveries times to the queue named after this one with -poison added, making that queue if it is not there. A message on the poison queue stays until someone deletes it.

Verify

Upload a blob with a line you can recognize to the account, then find that line at the destination. The queue's message count returns to zero once Smeltr delivers it.

Troubleshooting

Nothing arrives
Check that the event subscription filters for Blob Created, sends to this queue, shows delivered events in its metrics, and has no subject filter that leaves out your blobs.
Messages pile up on the poison queue
The source cannot read their blobs: check the identity's role on the container, or that the blob's account is the source's account, and the worker log for the reason.

See also