Log Collection
SkySignal captures logs from your Meteor application automatically, giving you a centralized place to search, filter, and correlate log output with traces and errors.
What Gets Tracked
SkySignal intercepts logs from two sources:
Console methods - console.log, console.info, console.warn, console.error, and console.debug are all intercepted automatically. The original console output still works as normal; the agent just taps into it.
Meteor's Log package - If your app uses the logging package (most Meteor apps do), the agent also intercepts Log.info, Log.warn, Log.error, and Log.debug.
For each log entry, the agent captures:
| Field | Description |
|---|---|
level | Log level (debug, info, warn, error, fatal) |
message | The log message content |
timestamp | When the log was emitted |
source | Where it came from: console, meteor-log, or api (manual submission) |
metadata | Optional structured data attached to the log |
Automatic Method Context
When a log happens inside a running Meteor Method, the agent automatically attaches extra context:
| Field | Description |
|---|---|
methodName | The Method that was executing when the log was emitted |
traceId | The trace ID for that Method call |
userId | The user who called the Method |
sessionId | The DDP session ID |
This means you can click through from a log entry to the full Method trace, or see all logs that happened during a specific Method call. No extra code required on your part.
Configuration
All log collection settings go in the skysignal block of your settings.json:
{
"skysignal": {
"collectLogs": true,
"logLevels": ["info", "warn", "error", "fatal"],
"logSampleRate": 1.0,
"logMaxMessageLength": 10000,
"logCaptureConsole": true,
"logCaptureMeteorLog": true
}
}
| Option | Type | Default | Description |
|---|---|---|---|
collectLogs | Boolean | true | Master switch for log collection. Set to false to disable all log capture. |
logLevels | Array | ["info", "warn", "error", "fatal"] | Which log levels to capture. Levels not in this array are ignored. |
logSampleRate | Number | 1.0 | Fraction of logs to capture, from 0.0 (none) to 1.0 (all). |
logMaxMessageLength | Number | 10000 | Maximum character length for log messages. Messages longer than this are truncated. |
logCaptureConsole | Boolean | true | Whether to intercept console.log/info/warn/error/debug. |
logCaptureMeteorLog | Boolean | true | Whether to intercept Meteor's Log.info/warn/error/debug (requires the logging package). |
Manual Log Submission
Sometimes you want to log a specific business event that you know you always want captured, regardless of sampling settings. Use SkySignalAgent.addLog() for this:
import { SkySignalAgent } from 'meteor/skysignal:agent';
SkySignalAgent.addLog('info', 'User signed up', { userId: 'abc123', plan: 'pro' });
SkySignalAgent.addLog('error', 'Payment failed', { orderId: 'xyz', provider: 'stripe' });
The signature is addLog(level, message, metadata). The metadata argument is optional and can be any plain object.
Logs submitted via addLog() are tagged with source "api" so you can distinguish them from automatically captured console/Meteor logs. They bypass logSampleRate -- manual logs are always captured (as long as collectLogs is true and the level is in logLevels).
Viewing Logs
Navigate to the Logs view in the sidebar to see your captured logs. From there you can:
- Search by message text (full-text search across log messages)
- Filter by level - Narrow down to just errors, warnings, etc.
- Filter by time range - Focus on a specific window
- Correlate with traces - Logs captured during a Method call link directly to the Method trace
- Correlate with errors - If an error was thrown in the same Method execution, the log entry links to it
This correlation is what makes centralized logging useful compared to just grepping your server output. When a user reports a problem, you can find the error, see the trace, and read every log line that happened during that request.
Sampling
For high-traffic applications, capturing every single log can generate a lot of data. Use logSampleRate to reduce the volume:
{
"skysignal": {
"logSampleRate": 0.1
}
}
A value of 0.1 means roughly 10% of logs are captured. The sampling is random and applied per log entry.
A few things to keep in mind with sampling:
- Errors and warnings are often more valuable than info/debug -- consider keeping
logSampleRateat1.0and just removing"debug"and"info"fromlogLevelsinstead. - Manual logs via
SkySignalAgent.addLog()are not affected by sampling. They always get through. - Sampling is applied on the agent side, before data is sent to SkySignal, so it does reduce network and storage overhead.
Best Practices
Use logLevels to control volume in production
If your app logs a lot of debug/info output, skip those levels in production rather than sampling them:
{
"skysignal": {
"logLevels": ["warn", "error", "fatal"]
}
}
This way you always capture every warning and error, but skip the noisy stuff.
Use logSampleRate for high-throughput apps
If even your warn/error volume is high (thousands per minute), bring the sample rate down to keep costs and storage manageable. Start with 0.5 and adjust from there.
Use SkySignalAgent.addLog() for important business events
Things like user signups, payment completions, subscription changes -- these are events you always want captured regardless of sampling. Use the manual API for them:
SkySignalAgent.addLog('info', 'Subscription upgraded', {
userId,
oldPlan: 'starter',
newPlan: 'pro',
});
Keep metadata objects small
The metadata object is serialized and sent over the wire to SkySignal. Don't attach large objects like full database documents or request bodies. Stick to IDs, short strings, and numbers.
// Good: small, useful metadata
SkySignalAgent.addLog('error', 'Order processing failed', {
orderId: order._id,
step: 'payment',
amount: order.total,
});
// Bad: huge metadata
SkySignalAgent.addLog('error', 'Order processing failed', {
order, // entire document
cart, // entire cart object
userProfile, // entire profile
});
Troubleshooting
Logs Not Appearing
- Verify
collectLogsistrue(or not set -- it defaults totrue) - Check that the log level is included in
logLevels - If
logSampleRateis low, you may need to generate more logs before some get through - Make sure
logCaptureConsoleand/orlogCaptureMeteorLogare enabled for the source you expect
Logs Missing Method Context
Method context (methodName, traceId, etc.) is only attached when the log happens inside a Meteor Method execution context. Logs emitted from startup code, background jobs, or async callbacks that have left the Method fiber/async context will not have Method context attached.
Messages Are Truncated
If your log messages are being cut off, increase logMaxMessageLength. The default of 10,000 characters is generous for most use cases, but if you're logging large payloads you may need to bump it up.
Next Steps
- Error Tracking - Capture and diagnose application errors
- Live Query Monitoring - Monitor observer efficiency
- Alerting - Set up alerts based on log patterns