Yoto Sync uses structured logs and typed telemetry events to understand application behavior in development and production.
The logger and telemetry modules serve different purposes.
app/lib/logger.server.ts is the only
application-owned code that calls console.debug, console.info,
console.warn, or console.error.
Use the logger for diagnostic details that help explain how an operation ran:
- Sandbox lifecycle
- Cache hits and misses
- Upload milestones
- Transcode polling
- Recoverable upstream errors
Diagnostic messages use stable, machine-readable names:
logger.info({
message: "yoto.audio.upload.completed",
cardId,
trackId,
})Cloudflare and Sandbox SDK logs are emitted by dependencies and do not pass through the application logger.
app/lib/telemetry.server.ts defines typed product events. Use telemetry for meaningful user actions and their outcomes:
- Authentication
- Imports
- Card creation and deletion
- Track copy, deletion, icon assignment, reorder, and numbering
telemetry.info(EVENT.IMPORT.COMPLETED, {
importId,
cardId,
youtubeUrl,
sourceType,
splitByChapters,
durationMs,
sourceTrackCount,
sourceDurationSeconds,
added,
skipped,
chapterSplitUnavailable,
})Telemetry currently writes structured records through the logger. Both diagnostic logs and telemetry events are stored in Cloudflare Workers Logs.
The EVENT object is the canonical event
catalog. Do not maintain a duplicate event list in documentation.
Use levels consistently:
| Level | Use |
|---|---|
debug |
Repetitive internal details such as cache lookups and polling |
info |
Successful milestones and completed user operations |
warn |
Recoverable problems, rejected input, or expected upstream conditions |
error |
Operations that cannot complete or unexpected application failures |
Fast user mutations generally emit only completed or failed telemetry events. Long-running imports emit started, completed, and failed events.
Use lowercase dot-separated names:
<domain>.<operation>.<state>
Examples:
auth.login.failed
card.create.completed
track.copy.completed
import.failed
Diagnostic logger messages follow the same style but may include additional implementation detail:
yoto.audio.transcode.polled
import.sandbox.destroy_failed
Every telemetry event must have an entry in
TelemetryPayloads. This keeps event payloads
consistent and catches missing or invalid fields at compile time.
Prefer operational context:
- Card, import, and track identifiers
- Canonical public YouTube URLs for imports
- Source type and chapter-splitting mode
- Counts, sizes, durations, stages, and failure reasons
Never log:
- Authentication tokens or refresh tokens
- Cookies or encrypted credentials
- Signed upload URLs
- Request authorization headers
- Raw audio or image contents
- Feedback messages or email addresses
Avoid user-entered card titles unless they are required to diagnose a specific problem. Diagnostic audio logs may include source track titles supplied by YouTube.
To add a product event:
- Add its name to
EVENT. - Add its payload to
TelemetryPayloads. - Emit it only after the operation has reached the stated outcome.
- Add a focused test that verifies the event name, level, and important payload fields.
To add a diagnostic log:
- Choose a stable machine-readable
message. - Select the appropriate log level.
- Include only the context needed to investigate the operation.
- Use
loggerinstead of callingconsoledirectly.
During local development, records appear in the terminal running
npm run dev.
In production:
- Open the Cloudflare dashboard.
- Select Workers & Pages.
- Select the
yotoWorker. - Open Observability.
- Filter or group records by
event,message,level,reason,cardId, orimportId.
Cloudflare automatic tracing is enabled at 100% sampling during its initial evaluation. Traces include Worker handlers, fetch calls, and binding calls without custom application instrumentation.
Planned observability work:
- Evaluate trace coverage and choose a permanent sampling rate.
- Evaluate an OpenTelemetry destination when external dashboards or alerts are needed.
The logger should remain the structured logging boundary.