How to Forward Logs with advancedSink and rawTransforms
The typed LogForward outputs (kafka, elasticsearch, opensearch, syslog, http, console, blackhole, clickhouse) cover most forwarding scenarios. The advancedSink output is the escape hatch for everything else — it lets you pick any Vector sink by name and reshape events with a small, allowlisted set of Vector transforms before the sink writes.
Reach for advancedSink when:
- the destination is a vendor sink the platform does not expose as a typed output (
datadog_logs,humio_logs,aws_s3,nats,gcp_cloud_storage, …); - the destination needs a specific wire-format envelope that typed outputs do not produce (OTLP
resourceLogs/scopeLogs/logRecords, Splunk HEC batch, …); - the forward path needs richer event-level reshaping than the platform filters (
parse,filter,redact,prune,remapFields) can do — for example batch-aggregating many records into one request body, or writing a VRL predicate that combines multiple conditions.
If none of these apply, prefer a typed output and the standard filters in How to Forward Logs with LogForward — they have tighter validation and are easier to review.
TOC
PrerequisitesSpec shapeadvancedSink.componentTypeadvancedSink.parametersadvancedSink.rawTransforms[]Picking between a platform filters[] entry and a rawTransforms[] entryRecipesRecipe A — Forward audit records to Datadog, with pruning and enrichmentRecipe B — Forward platform logs to a generic HTTP intake, with a VRL filter and samplingRecipe C — Forward platform logs as OTLP envelopes to an OpenTelemetry CollectorVerifyLimits and NotesRelated TopicsPrerequisites
- Alauda Container Platform Log Storage Management installed, and
PlatformLogForward/platform-defaultisReady. See Installation. - The storage operator shipped in the v4.4 release carries the
advancedSink.rawTransformsfield and does not blockbatch/requestin parameters. The patterns in this document assume you are on that release. - Secrets referenced by
spec.output.authSecretRefandspec.output.tls.caSecretReflive incpaas-system.
LogForward lives in cpaas-system only
Same constraint as every other LogForward: the admission webhook validate-lf.log.alauda.io rejects any LogForward outside cpaas-system. The platform administrator, not the tenant, authors each CR.
Spec shape
advancedSink.componentType
Pick exactly one Vector sink type by name. The name matches what Vector uses in its own documentation — for example http, datadog_logs, humio_logs, aws_s3, nats, elasticsearch (if you want its full knob set rather than the platform's typed wrapper). The storage operator does not maintain a per-sink allowlist, because new Vector versions add sinks faster than any curated list can keep up. Vector validates the type at startup; if the name is wrong or the sink is gated behind a Vector feature flag that is off, the Vector pod fails to come up and the LogForward reports Ready=False with the parser error on status.conditions.
advancedSink.parameters
A free-form object whose keys mirror the chosen sink's Vector configuration. Nested objects translate to nested TOML tables ({"encoding": {"codec": "json"}} becomes [sinks.output.encoding] codec = "json").
Reserved keys (admission webhook rejects at the parameters top level):
Nested keys named the same (for example {"resource": {"type": "gce_instance"}}) are not rejected — the webhook only checks the parameters top level.
Previously reserved, now allowed: batch and request. Both are per-sink knobs; the OTLP envelope recipe below needs batch.max_events: 1 to work.
advancedSink.rawTransforms[]
An optional ordered chain of Vector transforms that runs after the platform filters and before the sink writes. Each entry has:
Why these six types? They are local, side-effect-free transforms — they do not change the topology, do not create sub-outputs, do not call external services. route (multi-output) breaks the operator's input wiring. lua (arbitrary code) is a safety hazard. log_to_metric belongs on the metrics pipeline.
Execution order inside the generated Vector pipeline:
The operator wires the inputs on every stage; you never write inputs yourself (and the webhook rejects it if you do).
Picking between a platform filters[] entry and a rawTransforms[] entry
The two overlap. The rule of thumb:
Mix them freely: the platform filters run first and do the easy field-level work, then rawTransforms do the heavier shape work on an already-clean event.
Recipes
Three worked examples, from simple to involved.
Recipe A — Forward audit records to Datadog, with pruning and enrichment
Scenario: ship platform audit records to Datadog Logs. Use the platform prune filter to drop noisy fields, then a rawTransforms.remap to add a tenant tag that Datadog can route on.
Points worth noting:
authSecretRef.password→OUTPUT_PASSWORDenv on the Vector pod →${OUTPUT_PASSWORD}literal inparametersexpands at Vector startup. Theusernamekey is required by the Secret shape but Datadog does not read it.- The platform
prunefilter runs before theremap, so the enrichment VRL operates on an already-smaller event. - VRL fallible operations (
to_string(x)) must carry a fallback (?? "unknown") or the whole transform aborts the event. For a full VRL recipe set see the operator-side guide atlog-storage-operator/docs/HOWTO_LF_ADVANCED_SINK_RAW_TRANSFORMS.md.
Recipe B — Forward platform logs to a generic HTTP intake, with a VRL filter and sampling
Scenario: ship application logs to a generic HTTP intake, but drop healthcheck noise with a composite condition the platform filter cannot express as a single predicate, and sample the surviving stream at 10% per pod to control volume.
Points worth noting:
- The platform
redactfilter and therawTransformsfilter/sampleare composed: redact first, then drop, then sample. - The
excludefield onsampleensures every error survives — a common ask you cannot express with the platformfilterfilter. - Vector's
httpsink refuses to start if bothauthSecretRefandparameters.request.headers.Authorizationare set. Pick one path (same rule as the typed HTTP output in How to Forward Logs with LogForward).
Recipe C — Forward platform logs as OTLP envelopes to an OpenTelemetry Collector
Scenario: ship platform logs to an OTel Collector's otlphttp receiver. OTLP/HTTP wants a single top-level JSON object ({resourceLogs: [...]}), not an array — so the recipe uses remap + reduce + remap to build the envelope, and batch.max_events: 1 on the sink so Vector does not re-batch the single produced envelope into an array.
Points worth noting:
batch.max_events: 1is required for OTLP/HTTP. Without it, Vector'shttpsink wraps the reducer's single envelope into a one-element array[{...}], which the OTel Collector rejects with 400.expire_after_mstrades latency against batch size. 1 second (shown) is a reasonable default; at very high volume reduce it to 500 ms, at very low volume raise it to 5 000 ms. Watch for the collector'smax_request_body_size— if envelopes exceed it, cutexpire_after_ms.- The timestamp (
timeUnixNano: "0") is a placeholder: the collector will use ingest time. To preserve the real event time, replace it withto_string(to_unix_timestamp(parse_timestamp!(.timestamp, "%+")) * 1000000000). - If the collector needs auth, add it to
parameters.request.headers.Authorization(Bearer ${OUTPUT_PASSWORD}) and setauthSecretRefwith the key in the Secret'spassword.
Verify
Same as any LogForward:
If it does not go Ready, read the conditions:
Common Ready=False reasons specific to advancedSink:
AdvancedSinkParametersRejected— a reserved key (type,inputs,sources,transforms,route,buffer,acknowledgements,healthcheck) is set at the parameters top level.RawTransformsRejected— arawTransforms[*]entry has a non-allowlistedtype, a duplicatename, or writesinputs/typeinside itsspec.VectorValidateFailed— the operator renders a Vector config, invokesvector validateas a pre-flight, and only rolls the Deployment if validation passes. The condition message carries the Vector parser error verbatim; it is almost always a typo in a Vector sink field name or a VRL syntax error (fallible without ??).
To debug the actual on-wire payload the sink is emitting, point the sink uri at a short-lived echo pod and read what arrives — the operator-side guide at log-storage-operator/docs/HOWTO_LF_ADVANCED_SINK_RAW_TRANSFORMS.md ships an echo-pod recipe you can copy.
Limits and Notes
rawTransforms[*].typeis restricted toremap,filter,reduce,throttle,sample,dedupe. Other Vector transform types (notablyrouteandlua) are rejected.rawTransforms[*].speccannot carryinputsortype— the operator wires them.- One
LogForwardhas exactly one output and one Vector Deployment. To fan out to many destinations, create manyLogForwardCRs; they can share platform filters by copy-paste only (there is no cross-CR filter re-use). - Platform filters (
filters[]) andrawTransforms[]are both run; filters first, rawTransforms second. Use the former for field-level ops, the latter for event-shape ops. - The platform's
KafkaUsermust include thelogforward-consumer-group prefix ACL rule. Without it the Vector pod silently reads zero records and theLogForwardstill reportsReady=True. See Installation for the ACL recipe. advancedSinkis an escape hatch. Vector sink schemas can change between Vector minor releases; the operator runsvector validateas a pre-flight on every reconcile and refuses to roll a broken config, so upgrades stay safe, but it is worth re-reading the Vector sink reference after a storage operator major upgrade.
Related Topics
- How to Forward Logs with LogForward — typed outputs (
kafka,elasticsearch,opensearch,syslog,http,console,blackhole,clickhouse) and the platform filter catalogue. - How to Archive Logs to Third-Party Storage — the
razor consumer --database-type=filearchival path, for NFS / S3 cold storage rather than real-time forwarding. - Installation — storage operator install and the
logforward-KafkaUser prefix ACL rule.