feat(国际化): 添加运维监控多语言支持
- 添加英文翻译(en.ts)包含 ops 监控所有文案 - 添加中文翻译(zh.ts)包含 ops 监控所有文案
This commit is contained in:
@@ -131,6 +131,7 @@ export default {
|
||||
noData: 'No data',
|
||||
success: 'Success',
|
||||
error: 'Error',
|
||||
critical: 'Critical',
|
||||
warning: 'Warning',
|
||||
info: 'Info',
|
||||
active: 'Active',
|
||||
@@ -145,6 +146,8 @@ export default {
|
||||
copiedToClipboard: 'Copied to clipboard',
|
||||
copyFailed: 'Failed to copy',
|
||||
contactSupport: 'Contact Support',
|
||||
add: 'Add',
|
||||
invalidEmail: 'Please enter a valid email address',
|
||||
selectOption: 'Select an option',
|
||||
searchPlaceholder: 'Search...',
|
||||
noOptionsFound: 'No options found',
|
||||
@@ -177,6 +180,7 @@ export default {
|
||||
accounts: 'Accounts',
|
||||
proxies: 'Proxies',
|
||||
redeemCodes: 'Redeem Codes',
|
||||
ops: 'Ops',
|
||||
settings: 'Settings',
|
||||
myAccount: 'My Account',
|
||||
lightMode: 'Light Mode',
|
||||
@@ -1713,6 +1717,370 @@ export default {
|
||||
failedToLoad: 'Failed to load usage records'
|
||||
},
|
||||
|
||||
// Ops Monitoring
|
||||
ops: {
|
||||
title: 'Ops Monitoring',
|
||||
description: 'Operational monitoring and troubleshooting',
|
||||
// Dashboard
|
||||
systemHealth: 'System Health',
|
||||
overview: 'Overview',
|
||||
noSystemMetrics: 'No system metrics collected yet.',
|
||||
collectedAt: 'Collected at:',
|
||||
window: 'window',
|
||||
cpu: 'CPU',
|
||||
memory: 'Memory',
|
||||
db: 'DB',
|
||||
redis: 'Redis',
|
||||
goroutines: 'Goroutines',
|
||||
jobs: 'Jobs',
|
||||
active: 'active',
|
||||
idle: 'idle',
|
||||
ok: 'ok',
|
||||
lastRun: 'last_run:',
|
||||
lastSuccess: 'last_success:',
|
||||
lastError: 'last_error:',
|
||||
noData: 'No data.',
|
||||
loadingText: 'loading',
|
||||
ready: 'ready',
|
||||
requestsTotal: 'Requests (total)',
|
||||
slaScope: 'SLA scope:',
|
||||
tokens: 'Tokens',
|
||||
tps: 'TPS:',
|
||||
current: 'current',
|
||||
peak: 'peak',
|
||||
sla: 'SLA (excl business limits)',
|
||||
businessLimited: 'business_limited:',
|
||||
errors: 'Errors',
|
||||
errorRate: 'error_rate:',
|
||||
upstreamRate: 'upstream_rate:',
|
||||
latencyDuration: 'Latency (duration_ms)',
|
||||
ttftLabel: 'TTFT (first_token_ms)',
|
||||
p50: 'p50:',
|
||||
p90: 'p90:',
|
||||
p95: 'p95:',
|
||||
p99: 'p99:',
|
||||
avg: 'avg:',
|
||||
max: 'max:',
|
||||
qps: 'QPS',
|
||||
requests: 'Requests',
|
||||
upstream: 'Upstream',
|
||||
client: 'Client',
|
||||
system: 'System',
|
||||
other: 'Other',
|
||||
errorsSla: 'Errors (SLA scope)',
|
||||
upstreamExcl429529: 'Upstream (excl 429/529)',
|
||||
failedToLoadData: 'Failed to load ops data.',
|
||||
tpsK: 'TPS (K)',
|
||||
top: 'Top:',
|
||||
throughputTrend: 'Throughput Trend',
|
||||
latencyHistogram: 'Latency Histogram',
|
||||
errorTrend: 'Error Trend',
|
||||
errorDistribution: 'Error Distribution',
|
||||
// Error Log
|
||||
errorLog: {
|
||||
timeId: 'Time / ID',
|
||||
context: 'Context',
|
||||
status: 'Status',
|
||||
message: 'Message',
|
||||
latency: 'Latency',
|
||||
action: 'Action',
|
||||
noErrors: 'No errors in this window.',
|
||||
grp: 'GRP:',
|
||||
acc: 'ACC:',
|
||||
details: 'Details',
|
||||
phase: 'Phase'
|
||||
},
|
||||
// Error Details Modal
|
||||
errorDetails: {
|
||||
upstreamErrors: 'Upstream Errors',
|
||||
requestErrors: 'Request Errors',
|
||||
total: 'Total:',
|
||||
searchPlaceholder: 'Search request_id / client_request_id / message',
|
||||
accountIdPlaceholder: 'account_id'
|
||||
},
|
||||
// Error Detail Modal
|
||||
errorDetail: {
|
||||
loading: 'Loading…',
|
||||
requestId: 'Request ID',
|
||||
time: 'Time',
|
||||
phase: 'Phase',
|
||||
status: 'Status',
|
||||
message: 'Message',
|
||||
basicInfo: 'Basic Info',
|
||||
platform: 'Platform',
|
||||
model: 'Model',
|
||||
latency: 'Latency',
|
||||
ttft: 'TTFT',
|
||||
businessLimited: 'Business Limited',
|
||||
requestPath: 'Request Path',
|
||||
timings: 'Timings',
|
||||
auth: 'Auth',
|
||||
routing: 'Routing',
|
||||
upstream: 'Upstream',
|
||||
response: 'Response',
|
||||
retry: 'Retry',
|
||||
retryClient: 'Retry (Client)',
|
||||
retryUpstream: 'Retry (Upstream pinned)',
|
||||
pinnedAccountId: 'Pinned account_id',
|
||||
retryNotes: 'Retry Notes',
|
||||
requestBody: 'Request Body',
|
||||
errorBody: 'Error Body',
|
||||
trimmed: 'trimmed',
|
||||
confirmRetry: 'Confirm Retry',
|
||||
retrySuccess: 'Retry succeeded',
|
||||
retryFailed: 'Retry failed',
|
||||
na: 'N/A',
|
||||
retryHint: 'Retry will resend the request with the same parameters',
|
||||
retryClientHint: 'Use client retry (no account pinning)',
|
||||
retryUpstreamHint: 'Use upstream pinned retry (pin to the error account)',
|
||||
pinnedAccountIdHint: '(auto from error log)',
|
||||
retryNote1: 'Retry will use the same request body and parameters',
|
||||
retryNote2: 'If the original request failed due to account issues, pinned retry may still fail',
|
||||
retryNote3: 'Client retry will reselect an account',
|
||||
confirmRetryMessage: 'Confirm retry this request?',
|
||||
confirmRetryHint: 'Will resend with the same request parameters'
|
||||
},
|
||||
requestDetails: {
|
||||
title: 'Request Details',
|
||||
details: 'Details',
|
||||
rangeLabel: 'Window: {range}',
|
||||
rangeMinutes: '{n} minutes',
|
||||
rangeHours: '{n} hours',
|
||||
empty: 'No requests in this window.',
|
||||
emptyHint: 'Try a different time range or remove filters.',
|
||||
failedToLoad: 'Failed to load request details',
|
||||
requestIdCopied: 'Request ID copied',
|
||||
copyFailed: 'Copy failed',
|
||||
copy: 'Copy',
|
||||
viewError: 'View Error',
|
||||
kind: {
|
||||
success: 'SUCCESS',
|
||||
error: 'ERROR'
|
||||
},
|
||||
table: {
|
||||
time: 'Time',
|
||||
kind: 'Kind',
|
||||
platform: 'Platform',
|
||||
model: 'Model',
|
||||
duration: 'Duration',
|
||||
status: 'Status',
|
||||
requestId: 'Request ID',
|
||||
actions: 'Actions'
|
||||
}
|
||||
},
|
||||
alertEvents: {
|
||||
title: 'Alert Events',
|
||||
description: 'Recent alert firing/resolution records (email-only)',
|
||||
loading: 'Loading...',
|
||||
empty: 'No alert events',
|
||||
loadFailed: 'Failed to load alert events',
|
||||
table: {
|
||||
time: 'Time',
|
||||
status: 'Status',
|
||||
severity: 'Severity',
|
||||
title: 'Title',
|
||||
metric: 'Metric / Threshold',
|
||||
email: 'Email Sent'
|
||||
}
|
||||
},
|
||||
alertRules: {
|
||||
title: 'Alert Rules',
|
||||
description: 'Create and manage threshold-based system alerts (email-only)',
|
||||
loading: 'Loading...',
|
||||
empty: 'No alert rules',
|
||||
loadFailed: 'Failed to load alert rules',
|
||||
saveFailed: 'Failed to save alert rule',
|
||||
deleteFailed: 'Failed to delete alert rule',
|
||||
create: 'Create Rule',
|
||||
createTitle: 'Create Alert Rule',
|
||||
editTitle: 'Edit Alert Rule',
|
||||
deleteConfirmTitle: 'Delete this rule?',
|
||||
deleteConfirmMessage: 'This will remove the rule and its related events. Continue?',
|
||||
metrics: {
|
||||
successRate: 'Success Rate (%)',
|
||||
errorRate: 'Error Rate (%)',
|
||||
p95: 'P95 Latency (ms)',
|
||||
p99: 'P99 Latency (ms)',
|
||||
cpu: 'CPU Usage (%)',
|
||||
memory: 'Memory Usage (%)',
|
||||
queueDepth: 'Concurrency Queue Depth'
|
||||
},
|
||||
table: {
|
||||
name: 'Name',
|
||||
metric: 'Metric',
|
||||
severity: 'Severity',
|
||||
enabled: 'Enabled',
|
||||
actions: 'Actions'
|
||||
},
|
||||
form: {
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
metric: 'Metric',
|
||||
operator: 'Operator',
|
||||
threshold: 'Threshold',
|
||||
severity: 'Severity',
|
||||
window: 'Window (minutes)',
|
||||
sustained: 'Sustained (samples)',
|
||||
cooldown: 'Cooldown (minutes)',
|
||||
enabled: 'Enabled',
|
||||
notifyEmail: 'Send email notifications'
|
||||
},
|
||||
validation: {
|
||||
title: 'Please fix the following issues',
|
||||
invalid: 'Invalid rule',
|
||||
nameRequired: 'Name is required',
|
||||
metricRequired: 'Metric is required',
|
||||
operatorRequired: 'Operator is required',
|
||||
thresholdRequired: 'Threshold must be a number',
|
||||
windowRange: 'Window must be one of: 1, 5, 60 minutes',
|
||||
sustainedRange: 'Sustained must be between 1 and 1440 samples',
|
||||
cooldownRange: 'Cooldown must be between 0 and 1440 minutes'
|
||||
}
|
||||
},
|
||||
runtime: {
|
||||
title: 'Ops Runtime Settings',
|
||||
description: 'Stored in database; changes take effect without editing config files.',
|
||||
loading: 'Loading...',
|
||||
noData: 'No runtime settings available',
|
||||
loadFailed: 'Failed to load runtime settings',
|
||||
saveSuccess: 'Runtime settings saved',
|
||||
saveFailed: 'Failed to save runtime settings',
|
||||
alertTitle: 'Alert Evaluator',
|
||||
groupAvailabilityTitle: 'Group Availability Monitor',
|
||||
evalIntervalSeconds: 'Evaluation Interval (seconds)',
|
||||
silencing: {
|
||||
title: 'Alert Silencing (Maintenance Mode)',
|
||||
enabled: 'Enable silencing',
|
||||
globalUntil: 'Silence until (RFC3339)',
|
||||
untilPlaceholder: '2026-01-05T00:00:00Z',
|
||||
untilHint: 'Leave empty to only toggle silencing without an expiry (not recommended).',
|
||||
reason: 'Reason',
|
||||
reasonPlaceholder: 'e.g., planned maintenance',
|
||||
entries: {
|
||||
title: 'Advanced: targeted silencing',
|
||||
hint: 'Optional: silence only certain rules or severities. Leave fields empty to match all.',
|
||||
add: 'Add Entry',
|
||||
empty: 'No targeted entries',
|
||||
entryTitle: 'Entry #{n}',
|
||||
ruleId: 'Rule ID (optional)',
|
||||
ruleIdPlaceholder: 'e.g., 1',
|
||||
severities: 'Severities (optional)',
|
||||
severitiesPlaceholder: 'e.g., P0,P1 (empty = all)',
|
||||
until: 'Until (RFC3339)',
|
||||
reason: 'Reason',
|
||||
validation: {
|
||||
untilRequired: 'Entry until time is required',
|
||||
untilFormat: 'Entry until time must be a valid RFC3339 timestamp',
|
||||
ruleIdPositive: 'Entry rule_id must be a positive integer',
|
||||
severitiesFormat: 'Entry severities must be a comma-separated list of P0..P3'
|
||||
}
|
||||
},
|
||||
validation: {
|
||||
timeFormat: 'Silence time must be a valid RFC3339 timestamp'
|
||||
}
|
||||
},
|
||||
lockEnabled: 'Distributed Lock Enabled',
|
||||
lockKey: 'Distributed Lock Key',
|
||||
lockTTLSeconds: 'Distributed Lock TTL (seconds)',
|
||||
showAdvancedDeveloperSettings: 'Show advanced developer settings (Distributed Lock)',
|
||||
advancedSettingsSummary: 'Advanced settings (Distributed Lock)',
|
||||
evalIntervalHint: 'How often the evaluator runs. Keeping the default is recommended.',
|
||||
validation: {
|
||||
title: 'Please fix the following issues',
|
||||
invalid: 'Invalid settings',
|
||||
evalIntervalRange: 'Evaluation interval must be between 1 and 86400 seconds',
|
||||
lockKeyRequired: 'Distributed lock key is required when lock is enabled',
|
||||
lockKeyPrefix: 'Distributed lock key must start with "{prefix}"',
|
||||
lockKeyHint: 'Recommended: start with "{prefix}" to avoid conflicts',
|
||||
lockTtlRange: 'Distributed lock TTL must be between 1 and 86400 seconds'
|
||||
}
|
||||
},
|
||||
email: {
|
||||
title: 'Email Notification',
|
||||
description: 'Configure alert/report email notifications (stored in database).',
|
||||
loading: 'Loading...',
|
||||
noData: 'No email notification config',
|
||||
loadFailed: 'Failed to load email notification config',
|
||||
saveSuccess: 'Email notification config saved',
|
||||
saveFailed: 'Failed to save email notification config',
|
||||
alertTitle: 'Alert Emails',
|
||||
reportTitle: 'Report Emails',
|
||||
recipients: 'Recipients',
|
||||
recipientsHint: 'If empty, the system may fallback to the first admin email.',
|
||||
minSeverity: 'Min Severity',
|
||||
minSeverityAll: 'All severities',
|
||||
rateLimitPerHour: 'Rate limit per hour',
|
||||
batchWindowSeconds: 'Batch window (seconds)',
|
||||
includeResolved: 'Include resolved alerts',
|
||||
dailySummary: 'Daily summary',
|
||||
weeklySummary: 'Weekly summary',
|
||||
errorDigest: 'Error digest',
|
||||
errorDigestMinCount: 'Min errors for digest',
|
||||
accountHealth: 'Account health',
|
||||
accountHealthThreshold: 'Error rate threshold (%)',
|
||||
cronPlaceholder: 'Cron expression',
|
||||
reportHint: 'Schedules use cron syntax; leave empty to use defaults.',
|
||||
validation: {
|
||||
title: 'Please fix the following issues',
|
||||
invalid: 'Invalid email notification config',
|
||||
alertRecipientsRequired: 'Alert emails are enabled but no recipients are configured',
|
||||
reportRecipientsRequired: 'Report emails are enabled but no recipients are configured',
|
||||
invalidRecipients: 'One or more recipient emails are invalid',
|
||||
rateLimitRange: 'Rate limit per hour must be a number ≥ 0',
|
||||
batchWindowRange: 'Batch window must be between 0 and 86400 seconds',
|
||||
cronRequired: 'A cron expression is required when schedule is enabled',
|
||||
cronFormat: 'Cron expression format looks invalid (expected at least 5 parts)',
|
||||
digestMinCountRange: 'Min errors for digest must be a number ≥ 0',
|
||||
accountHealthThresholdRange: 'Account health threshold must be between 0 and 100'
|
||||
}
|
||||
},
|
||||
concurrency: {
|
||||
title: 'Concurrency / Queue',
|
||||
byPlatform: 'By Platform',
|
||||
byGroup: 'By Group',
|
||||
byAccount: 'By Account',
|
||||
totalRows: '{count} rows',
|
||||
disabledHint: 'Realtime monitoring is disabled in settings.',
|
||||
empty: 'No data',
|
||||
queued: 'Queue {count}',
|
||||
rateLimited: 'Rate-limited {count}',
|
||||
errorAccounts: 'Errors {count}',
|
||||
loadFailed: 'Failed to load concurrency data'
|
||||
},
|
||||
realtime: {
|
||||
connected: 'Realtime connected',
|
||||
connecting: 'Realtime connecting',
|
||||
reconnecting: 'Realtime reconnecting',
|
||||
offline: 'Realtime offline',
|
||||
closed: 'Realtime closed',
|
||||
reconnectIn: 'retry in {seconds}s'
|
||||
},
|
||||
queryMode: {
|
||||
auto: 'Auto',
|
||||
raw: 'Raw',
|
||||
preagg: 'Preagg'
|
||||
},
|
||||
accountAvailability: {
|
||||
available: 'Available',
|
||||
unavailable: 'Unavailable',
|
||||
accountError: 'Error'
|
||||
},
|
||||
tooltips: {
|
||||
throughputTrend: 'Requests/QPS + Tokens/TPS in the selected window.',
|
||||
latencyHistogram: 'Latency distribution (duration_ms) for successful requests.',
|
||||
errorTrend: 'Error counts over time (SLA scope excludes business limits; upstream excludes 429/529).',
|
||||
errorDistribution: 'Error distribution by status code.'
|
||||
},
|
||||
charts: {
|
||||
emptyRequest: 'No requests in this window.',
|
||||
emptyError: 'No errors in this window.',
|
||||
resetZoom: 'Reset',
|
||||
resetZoomHint: 'Reset zoom (if enabled)',
|
||||
downloadChart: 'Download',
|
||||
downloadChartHint: 'Download chart as image'
|
||||
}
|
||||
},
|
||||
|
||||
// Settings
|
||||
settings: {
|
||||
title: 'System Settings',
|
||||
@@ -1803,6 +2171,20 @@ export default {
|
||||
sending: 'Sending...',
|
||||
enterRecipientHint: 'Please enter a recipient email address'
|
||||
},
|
||||
opsMonitoring: {
|
||||
title: 'Ops Monitoring',
|
||||
description: 'Enable ops monitoring for troubleshooting and health visibility',
|
||||
disabled: 'Ops monitoring is disabled',
|
||||
enabled: 'Enable Ops Monitoring',
|
||||
enabledHint: 'Enable the ops monitoring module (admin only)',
|
||||
realtimeEnabled: 'Enable Realtime Monitoring',
|
||||
realtimeEnabledHint: 'Enable realtime QPS/metrics push (WebSocket)',
|
||||
queryMode: 'Default Query Mode',
|
||||
queryModeHint: 'Default query mode for Ops Dashboard (auto/raw/preagg)',
|
||||
queryModeAuto: 'Auto (recommended)',
|
||||
queryModeRaw: 'Raw (most accurate, slower)',
|
||||
queryModePreagg: 'Preagg (fastest, requires aggregation)'
|
||||
},
|
||||
adminApiKey: {
|
||||
title: 'Admin API Key',
|
||||
description: 'Global API key for external system integration with full admin access',
|
||||
|
||||
Reference in New Issue
Block a user