const sfRequestDuration = new Histogram({
name: 'salesforce_request_duration_seconds',
help: 'Salesforce API request duration',
labelNames: ['operation', 'sobject'],
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
registers: [registry],
});
const sfRequestCounter = new Counter({
name: 'salesforce_requests_total',
help: 'Total Salesforce API requests',
labelNames: ['operation', 'sobject', 'status'],
registers: [registry],
});
const sfErrorCounter = new Counter({
name: 'salesforce_errors_total',
help: 'Salesforce errors by error code',
labelNames: ['error_code', 'sobject'],
registers: [registry],
});
async function instrumentedSfCall<T>(
operation: string,
sobject: string,
fn: () => Promise<T>
): Promise<T> {
const timer = sfRequestDuration.startTimer({ operation, sobject });
try {
const result = await fn();
sfRequestCounter.inc({ operation, sobject, status: 'success' });
return result;
} catch (error: any) {
const errorCode = error.errorCode || 'UNKNOWN';
sfRequestCounter.inc({ operation, sobject, status: 'error' });
sfErrorCounter.inc({ error_code: errorCode, sobject });
throw error;
} finally {
timer();
}
}
const accounts = await instrumentedSfCall('query', 'Account', () =>
conn.query('SELECT Id, Name FROM Account LIMIT 10')
);
async function getApiUsageEvents(days: number = 1) {
const conn = await getConnection();
const events = await conn.query(`
SELECT Id, EventType, LogDate, LogFileLength
FROM EventLogFile
WHERE EventType IN ('API', 'RestApi', 'BulkApi')
AND LogDate >= LAST_N_DAYS:${days}
ORDER BY LogDate DESC
`);
for (const event of events.records) {
const logContent = await conn.request(
`/services/data/v59.0/sobjects/EventLogFile/${event.Id}/LogFile`
);
console.log(`${event.EventType} on ${event.LogDate}: ${event.LogFileLength} bytes`);
}
}
import pino from 'pino';
const logger = pino({ name: 'salesforce-integration' });
function logSfOperation(
operation: string,
sobject: string,
details: Record<string, any>,
durationMs: number
) {
logger.info({
service: 'salesforce',
operation,
sobject,
durationMs,
...details,
});
}
groups:
- name: salesforce_alerts
rules:
- alert: SalesforceApiLimitCritical
expr: salesforce_api_usage_percent > 90
for: 5m
labels:
severity: critical
annotations:
summary: "Salesforce API usage above 90% ({{ $value }}%)"
description: "API calls will be blocked at 100%. Reduce usage or contact Salesforce for limit increase."
- alert: SalesforceApiLimitWarning
expr: salesforce_api_usage_percent > 75
for: 15m
labels:
severity: warning
annotations:
summary: "Salesforce API usage above 75%"
- alert: SalesforceHighErrorRate
expr: |
rate(salesforce_errors_total[5m]) /
rate(salesforce_requests_total[5m]) > 0.05
for: 5m
labels:
severity: warning
annotations:
summary: "Salesforce error rate > 5%"
- alert: SalesforceHighLatency
expr: |
histogram_quantile(0.95,
rate(salesforce_request_duration_seconds_bucket[5m])
) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "Salesforce P95 latency > 5s"
- alert: SalesforceAuthFailure
expr: increase(salesforce_errors_total{error_code="INVALID_SESSION_ID"}[5m]) > 0
labels:
severity: critical
annotations:
summary: "Salesforce authentication failures detected"