Skip to main content
Comprehensive logging and monitoring help you debug issues, track performance, and maintain reliability.

Log Key Events

Track every stage of webhook processing for complete observability.

What to Log

{
  "timestamp": "2025-01-15T10:30:45Z",
  "event": "webhook.received",
  "eventId": "abc123",
  "eventType": "VEHICLE_STATE",
  "vehicleId": "def456",
  "deliveryId": "ghi789"
}
{
  "timestamp": "2025-01-15T10:30:45Z",
  "event": "signature.verified",
  "eventId": "abc123",
  "valid": true
}
{
  "timestamp": "2025-01-15T10:30:46Z",
  "event": "processing.started",
  "eventId": "abc123",
  "eventType": "VEHICLE_STATE"
}
{
  "timestamp": "2025-01-15T10:30:47Z",
  "event": "processing.failed",
  "eventId": "abc123",
  "error": "Database connection timeout",
  "stackTrace": "..."
}

Critical Metrics

Monitor these metrics and set up alerts:
MetricWhat It MeasuresAlert Threshold
Signature verification failuresInvalid or spoofed requests> 5 in 5 minutes
Processing error rateCode or infrastructure issues> 5% of events
Queue depthProcessing backlog> 1000 messages
Response timeEndpoint performance> 10 seconds (approaching 15s timeout)
Duplicate processingIdempotency check hitsTrack for debugging
VEHICLE_ERROR rateSignal retrieval issues> 10% of vehicles

Implementation Examples

const winston = require('winston');

const logger = winston.createLogger({
  format: winston.format.json(),
  transports: [new winston.transports.Console()]
});

app.post('/webhooks/smartcar', async (req, res) => {
  const payload = req.body;
  const { eventId, eventType, vehicleId } = payload;
  
  // Log receipt
  logger.info('webhook.received', {
    eventId,
    eventType,
    vehicleId
  });
  
  // Verify signature
  const isValid = verifySignature(req.rawBody, req.headers['sc-signature']);
  logger.info('signature.verified', { eventId, valid: isValid });
  
  if (!isValid) {
    logger.warn('signature.failed', {
      eventId,
      sourceIp: req.ip
    });
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Queue and return
  await queue.add(payload);
  res.status(200).json({ status: 'received' });
});

async function processWebhook(payload) {
  const { eventId } = payload;
  const startTime = Date.now();
  
  logger.info('processing.started', { eventId });
  
  try {
    await updateVehicleData(payload);
    logger.info('processing.completed', {
      eventId,
      durationMs: Date.now() - startTime
    });
  } catch (error) {
    logger.error('processing.failed', {
      eventId,
      error: error.message,
      stack: error.stack
    });
    throw error;
  }
}

Next Steps