CLICLItypeA command you run, rather than a dependency you import.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →

@saptools/cf-tail

A command line that tails every started app in a Cloud Foundry space at once and merges their logs into one timeline by timestamp, with filters by level, tenant, router status and time window.

When a request crosses several apps in one Cloud Foundry space, cf logs still shows one app per terminal. This command line discovers the started apps in a region, org and space, fetches their recent logs in parallel (four at a time by default) or streams them live, and merges the rows by timestamp with each row labelled by its app; a running stream re-runs cf apps every 30 seconds to pick up apps that start or stop. Rows can be filtered across apps by level, tenant, router status range and time window, cf-tail summary counts levels, statuses and tenants per app, and the current SAP email and password are redacted before anything is printed or saved. Parsing and per-app storage come from @saptools/cf-logs, which it installs as a dependency, and any other secret an application logs is redacted only when passed with --extra-secret.

Facts

Latestv0.2.2ReleasedLast pushLicenceMIT

Where it sits

Lives in
Provides
LoggingBTPLoggingcapabilitySeeing what a running service did, in a form something can read afterwards — levels, a formatter that suits a laptop and one that suits a log service.
Runs
Cloud Foundry
Requires
@saptools/cf-logs@saptools/cf-logsartifactParses each app's log rows and keeps the per-app snapshots in its store; cf-tail adds discovery, merging and the aggregate store.Node.jsNode.jsoutside the atlasThe command line runs on Node.js 20 or later, beside the official cf CLI on the path.

Who is behind it

Đông TrầnĐông TrầnPersonMaintains this
In the atlas: maintains 18, contributes to 18
@dongitran
maintainer

What it declares

Every artifact

Type
CLI
Origin
Independently maintained
Runs on
Cloud Foundry

As a CLI

Distributed through
npm

Connections3

Install

npm add @saptools/cf-tail

Derived from the package name. No recipe recorded; the README has the configuration.

Where @saptools/cf-tail runsBy its type: a CLI is run from a terminalcallsdocumentedrequiresdocumentedrequiresYour terminal, actorYour terminalNode.js, systemNode.jssystem@saptools/cf-tail, module@saptools/cf-tail@saptools/cf-logs, module@saptools/cf-logs
SAPnot SAP's, or the project's ownstated in the documentdocumented only

README

quoted from dongitran/saptools under MIT, read
dongitran/saptools/packages/cf-tail/README.mdOn GitHub

🛰️ @saptools/cf-tail

Tail every app in a Cloud Foundry space at once — chronologically merged, filtered, and redacted.

Built on top of @saptools/cf-logs. Discover all started apps in a region/org/space, fetch their recent logs in parallel, and stream them live into a single multiplexed feed with strong filtering and bounded local persistence.

npm version license node

Install • Quick Start • CLI • Store • Security


✨ Features

  • 📥 Space-wide snapshots — fetch recent logs for every started app in a CF space in parallel, with a configurable concurrency limit.
  • 🧬 Chronological merge — every row carries its appName and rows from all apps are merged by timestamp into a single timeline.
  • 📡 Multiplexed live stream — one cf-tail stream process tails every app at once, with per-app color, prefixed labels, and auto-rediscovery as apps appear or disappear.
  • 🎯 Powerful selection — --apps a,b, --include-regex, --exclude, --exclude-regex to scope the fan-out.
  • 🧰 Cross-app filtering — level, search, source, tenant, status range, stream (out/err), --since/--until time windows, --max-rows.
  • 📊 Summary view — cf-tail summary aggregates level counts, source buckets, status buckets, tenants, first/last timestamps per app.
  • 🚨 Errors shortcut — cf-tail errors is snapshot --level error across the whole space.
  • 🔐 Redaction — SAP credentials are redacted before any output or persistence; you can add custom secrets via --extra-secret or programmatic options.
  • 🗃️ Bounded local store — aggregate snapshots cached at ~/.saptools/cf-tail-store.json with atomic writes and locking. Per-app raw logs continue to live in the cf-logs store.
  • 🧪 Fake-backed e2e — discovery, snapshot, stream, summary flows all pass without live SAP access.

📦 Install

# Global CLI
npm install -g @saptools/cf-tail

# Or as a dependency
npm install @saptools/cf-tail
# pnpm add @saptools/cf-tail
# yarn add @saptools/cf-tail

Note

Requires Node.js >= 20 and the official cf CLI on PATH.


Updates

Every command first checks npm for a newer @saptools/cf-tail (at most once an hour, one small request with a 2-second timeout) and, when one exists, installs that exact version with the package manager that owns the running binary and re-runs the command you typed on the new version. Both steps are announced on stderr; nothing is printed when the install is already current:

cf-tail: updating 0.2.0 -> 0.3.0 ...
cf-tail: updated to 0.3.0; re-running the command

If the install cannot complete, one stderr line gives the manual command and the command runs on the installed version; that version is not retried for a day. cf-tail self-update forces the check and install now; cf-tail self-update --check only reports.

ControlEffect
SAPTOOLS_AUTO_UPDATE=on|notify|offon (default) installs and re-runs; notify prints the manual command once per version; off never checks. Applies to every @saptools CLI.
CF_TAIL_AUTO_UPDATEsame values, this CLI only; wins over the global variable
SAPTOOLS_UPDATE_INTERVAL_MINUTESminutes between checks (default 60; 0 checks on every run)
SAPTOOLS_NPM_REGISTRYregistry to check and install from (default: npm's configured registry, then npmjs)
SAPTOOLS_UPDATE_DEBUG=1explain on stderr why nothing happened

The updater switches itself off in CI (CI set), under NODE_ENV=test or NO_UPDATE_NOTIFIER, when the binary runs from a source checkout, an npm link or an npx cache, and inside the re-run itself. It never writes to stdout, never asks for input, never uses sudo, and never moves onto a prerelease. Its state lives in ~/.saptools/updates/.

🚀 Quick Start

# 1. Export credentials used for cf api/auth
export SAP_EMAIL="sample@example.com"
export SAP_PASSWORD="sample-password"

# 2. List every started app in a space
cf-tail apps --region ap10 --org sample-org --space sample

# 3. One-shot snapshot of every app, merged by timestamp
cf-tail snapshot --region ap10 --org sample-org --space sample

# 4. Live tail of every app, with per-app colors
cf-tail stream --region ap10 --org sample-org --space sample

🧰 CLI

Shared session flags
FlagDescription
--region <key>CF region key such as ap10
--api-endpoint <url>Explicit CF API endpoint instead of a region key
--org <name>CF org name
--space <name>CF space name
--email <value>Override SAP_EMAIL
--password <value>Override SAP_PASSWORD
App-selection flags
FlagDescription
--apps <a,b>Comma-separated app names to include (alias for --include)
--include <name>Include a specific app name (repeatable)
--exclude <name>Exclude a specific app name (repeatable)
--include-regex <pattern>Include apps matching the regex (repeatable)
--exclude-regex <pattern>Exclude apps matching the regex (repeatable)
Row filter flags (snapshot, errors, summary, stream)
FlagDescription
--level <name>trace, debug, info, warn, error, fatal, or all
--search <text>Case-insensitive substring filter against the searchable row text
--source <text>Filter rows whose CF source contains the given text
--tenant <id>Filter rows whose parsed router tenant id matches
--status <range>Filter router status: 500, 5xx, or 400-499
--stream <value>Filter by out, err, or all
--since <duration>Keep rows newer than now - duration (e.g. 30s, 5m, 1h)
--until <duration>Drop rows older than now - duration
--max-rows <count>Maximum rows in the rendered output
--newest-firstRender newest-first instead of oldest-first
Output flags
FlagDescription
--jsonEmit a single structured JSON object (snapshot, summary)
--ndjsonEmit line-delimited JSON rows (snapshot, stream)
--by-appGroup rendered rows by app instead of merged timeline
--no-colorDisable ANSI colors. Honors NO_COLOR env; FORCE_COLOR overrides for non-TTY pipelines
--show-sourceInclude the CF source segment in text output
--truncate <chars>Truncate text-mode messages longer than the given character count
Redaction flags
FlagDescription
--extra-secret <value>Add a custom redaction (repeatable). Each occurrence is replaced with *** in output and storage
cf-tail apps
cf-tail apps \
  --region ap10 \
  --org sample-org \
  --space sample \
  --include-regex "^demo-" \
  --exclude demo-canary \
  --json
cf-tail snapshot

Fetches recent logs for every matching app in parallel, merges into a single chronological timeline, applies row filters, and optionally persists.

cf-tail snapshot \
  --region ap10 \
  --org sample-org \
  --space sample \
  --apps demo-app,api-app \
  --level error \
  --since 30m \
  --max-rows 100 \
  --json
Snapshot-only flagDescription
--savePersist redacted per-app snapshots to the cf-logs store and an aggregate entry to the cf-tail store
--concurrency <n>Maximum apps fetched in parallel (default 4)
--log-limit <count>Maximum parsed rows and bounded raw-text size per app
cf-tail errors

Shortcut for snapshot --level error:

cf-tail errors --region ap10 --org sample-org --space sample --since 1h
cf-tail summary

Aggregate counts for every matching app:

cf-tail summary \
  --region ap10 \
  --org sample-org \
  --space sample \
  --json
cf-tail stream

Multiplex live logs for every matching app. By default, the runtime re-discovers the app list every 30 seconds, picking up newly started apps and dropping stopped ones. Use --rediscover off (or --rediscover 0s) to disable.

cf-tail stream \
  --region ap10 \
  --org sample-org \
  --space sample \
  --include-regex "^api-" \
  --rediscover 60s
Stream-only flagDescription
--max-lines <count>Stop after emitting N rows
--rediscover <duration>Re-discover the app list at this interval (e.g. 30s, 2m, off)
--flush-interval-ms <ms>Batch window before append events are emitted
--retry-initial-ms <ms>Initial reconnect delay after unexpected stream exits
--retry-max-ms <ms>Maximum reconnect delay
--log-limit <count>Maximum parsed rows and bounded raw-text size per app
--savePersist bounded redacted stream appends into the cf-logs store
-q, --quietSuppress discovery and stream-state messages on stderr (text mode only)
cf-tail store path | list | clear
cf-tail store path
cf-tail store list
cf-tail store list --json
cf-tail store clear
cf-tail --version

Prints the installed @saptools/cf-tail semantic version.


📁 Store File

The aggregate cf-tail store lives here:

~/.saptools/cf-tail-store.json

It contains one entry per (apiEndpoint, org, space) with:

  • fetchedAt, updatedAt
  • appCount, rowCount
  • apps: [{ appName, rowCount, truncated }, ...]

Per-app raw text continues to live in the existing cf-logs store at ~/.saptools/cf-logs-store.json (used when you pass --save). The cf-tail store is metadata only.

Prefer readTailStore(), persistTailSnapshot(), cf-tail store path, or cf-tail store list over parsing the file directly.


🔐 Security Notes

  • The runtime redacts the current SAP email and password before emitting or persisting log content. Pass extraSecrets (programmatic) or --extra-secret <value> (CLI, repeatable) to add custom redaction rules.
  • Persisted snapshots are bounded and written with file locking plus atomic replace semantics.
  • Neither store file is safe for public repositories. Even after redaction, they still reveal app names, org names, spaces, endpoints, and log content.
  • If your application logs contain additional secrets beyond SAP credentials, add custom runtime redaction rules before persisting or forwarding output.

❓ FAQ

How is this different from @saptools/cf-logs?

cf-logs is single-app focused: one --app per CLI invocation, one key per store entry, one redaction set. cf-tail is multi-app: discovery, parallel snapshot, multiplexed live stream, chronological merge, cross-app filtering, and an aggregate store. It builds on cf-logs, not against it.

Do I still need cf-logs installed?

cf-tail depends on @saptools/cf-logs automatically. Install @saptools/cf-tail and you get both.

Does stream automatically pick up new apps?

Yes — every --rediscover interval the runtime re-runs cf apps, computes the diff, starts streams for new apps, and stops streams for apps that are no longer started.

How do I scope to a single app?

--apps demo-app (or --include demo-app). Same shape as cf-logs's single-app commands once you scope down.


🛠️ Development

From the monorepo root:

pnpm install
pnpm --filter @saptools/cf-tail cspell
pnpm --filter @saptools/cf-tail lint
pnpm --filter @saptools/cf-tail typecheck
pnpm --filter @saptools/cf-tail test:unit
pnpm --filter @saptools/cf-tail test:e2e
pnpm --filter @saptools/cf-tail build
pnpm --filter @saptools/cf-tail check

🤝 Author

Maintained by dongtran.

MIT, read

History

Latest

v0.2.2

  1. v0.2.1

  2. v0.2.0

  3. v0.1.3

  4. v0.1.2

  5. v0.1.1

  6. v0.1.0

On npm
0downloads per week, npm
Weekly downloads for @saptools/cf-tail26 complete calendar weeks from 2026-04-27 to 2026-10-25; the latest total is 0.27 Apr – 3 May: 04 May – 10 May: 32411 May – 17 May: 3318 May – 24 May: 1325 May – 31 May: 181 Jun – 7 Jun: 248 Jun – 14 Jun: 1615 Jun – 21 Jun: 422 Jun – 28 Jun: 5329 Jun – 5 Jul: 1936 Jul – 12 Jul: 2113 Jul – 19 Jul: 1120 Jul – 26 Jul: 1227 Jul – 2 Aug: 43 Aug – 9 Aug: 1910 Aug – 16 Aug: 1417 Aug – 23 Aug: 324 Aug – 30 Aug: 1131 Aug – 6 Sept: 3917 Sept – 13 Sept: 2014 Sept – 20 Sept: 1721 Sept – 27 Sept: 1128 Sept – 4 Oct: 55 Oct – 11 Oct: 812 Oct – 18 Oct: 619 Oct – 25 Oct: 0
Logging
  1. SAP Application Logging service for SAP BTPCollects Cloud Foundry or Kyma logs into a searchable Kibana
  2. SAP Cloud LoggingOpenSearch-based store for logs, metrics and traces
  3. @saptools/cf-logsLog fetcher and parser for one Cloud Foundry app

Details

Sources4
Added by handdiscovered herechecked
npm registry, @saptools/cf-tailversion, releases, installschecked
github.com/git+https://github.com/dongitran/saptools.gittree, pushes, contributors, CIchecked
packages/cf-tail/README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
deploymentCloud Foundry
latestv0.2.2
first release
releases and cadence7, ~2d median
discovered viaAdded by hand
first seen in the atlas
ecosystem and domainbtp, operations-and-runtime
History in the atlas1
  1. First seen.
For your agent
Ref
artifact:saptools-cf-tail
JSON
/artifacts/saptools-cf-tail.json
MCP
Connecting an agent