نمایش لاگهای خروجی کانتینر
لاگهای خروجی کانتینر را با فیلتر و پارسینگ timestamp نمایش میدهد.
🧩 دستور کلی
async getContainerLogs(containerId, options = {})
شرح عملکرد
این متد لاگهای خروجی کانتینر را بازیابی میکند. شامل:
- تأیید کانتینر موجود است
- دریافت لاگهای raw از container manager
- پارسینگ timestamps (روز هفته، تاریخ، ساعت)
- سازماندهی entries با timestamp و message
- فیلتر کردن بر اساس تعداد آخرین entries
- logging عملیات
مهم: لاگهای کانتینر در فایل متنی ذخیره میشوند. اگر فایل موجود نباشد، خطای 404 برگشت داده میشود.
ورودیها
| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
containerId | String | بله | شناسه یا نام کانتینر |
options | Object | بله | گزینههای لاگ |
options.number | Number | خیر | تعداد آخرین entries (پیشفرض: همه) |
options.follow | Boolean | خیر | دنبال کردن زنده (future feature) |
options.filter | String | خیر | فیلتر بر اساس کلیدواژه (future feature) |
خروجی
نوع: Array<Object> (لیست log entries)
هر entry شامل:
timestamp(String) - تاریخ و ساعتmessage(String) - متن لاگ (میتواند چند خطی باشد)
نمونه خروجی:
[
{
timestamp: "Sun Nov 30 14:30:45 UTC 2025",
message: "Container started successfully\nInitializing services..."
},
{
timestamp: "Sun Nov 30 14:31:02 UTC 2025",
message: "Service listening on port 8080"
},
{
timestamp: "Sun Nov 30 14:32:15 UTC 2025",
message: "Processing request from 192.168.1.100"
}
]
استثناها (Errors)
ResolveContainerName (500)
پیام: "Database error occurred while resolving container name or ID."
زمان رخ دادن: خطای دیتابیس در تطابق شناسه/نام کانتینر
جزئیات:
{
"type": "DB_ERROR",
"statusCode": 500,
"input": "container-id",
"error": "Database connection lost"
}
راهنمای حل:
- اتصال دیتابیس را بررسی کنید
- دیتابیس را راهاندازی کنید
ContainerNotFound (404)
پیام: "Container not found."
زمان رخ دادن: کانتینری با شناسه/نام درخواستی یافت نشود
جزئیات:
{
"type": "NOT_FOUND",
"statusCode": 404,
"containerId": "invalid-id"
}
راهنمای حل:
- شناسه کانتینر را بررسی کنید
listContainers()استفاده کنید تا تمام کانتینرها را ببینید- نام یا ID صحیح را وارد کنید
ContainerRecord (404)
پیام: "Container log file not found."
زمان رخ دادن: فایل لاگ کانتینر موجود نیست (کانتینر هنوز اجرا نشده)
جزئیات:
{
"type": "NOT_FOUND",
"statusCode": 404,
"containerId": "abc123def456",
"error": "ENOENT: no such file or directory"
}
راهنمای حل:
- کانتینر را
startContainer()یاrunContainer()استفاده کنید - کانتینر فعلاً هیچ لاگی تولید نکرده
- صبر کنید تا کانتینر خروجی تولید کند
GenericFailure (500)
پیام: "Generic failure during log retrieval."
زمان رخ دادن: خطای عمومی در دریافت لاگ
جزئیات:
{
"type": "GENERIC_ERROR",
"statusCode": 500,
"containerId": "abc123def456",
"error": "Read operation failed"
}
راهنمای حل:
- اجازههای فایل را بررسی کنید
- فضای دیسک را تأیید کنید
- لاگ فایل corrupt نباشد
مثالهای استفاده
مثال 1: دریافت تمام لاگها
const K3Core = require('k3-core');
(async () => {
const k3 = new K3Core();
try {
const logs = await k3.containerCore.getContainerLogs('my-container', {});
console.log(`Total entries: ${logs.length}`);
logs.forEach((entry) => {
console.log(`[${entry.timestamp}]`);
console.log(entry.message);
console.log('---');
});
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 2: دریافت آخرین ۱۰ لاگ
(async () => {
const k3 = new K3Core();
try {
const logs = await k3.containerCore.getContainerLogs('app-container', {
number: 10
});
console.log('Last 10 log entries:');
logs.forEach((entry, index) => {
console.log(`${index + 1}. [${entry.timestamp}]`);
console.log(` ${entry.message.split('\n')[0]}`);
});
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 3: دریافت لاگهای اخیر و جستجو
(async () => {
const k3 = new K3Core();
try {
const logs = await k3.containerCore.getContainerLogs('web-server', {
number: 50
});
const keyword = 'ERROR';
const filtered = logs.filter(entry =>
entry.message.includes(keyword)
);
console.log(`Found ${filtered.length} entries with "${keyword}":`);
filtered.forEach((entry) => {
console.log(`[${entry.timestamp}]`);
console.log(entry.message);
});
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 4: نمایش لاگها با رنگبندی
(async () => {
const k3 = new K3Core();
try {
const logs = await k3.containerCore.getContainerLogs('app', {
number: 100
});
logs.forEach((entry) => {
console.log(`\x1b[36m[${entry.timestamp}]\x1b[0m`);
// رنگبندی بر اساس محتوا
const lines = entry.message.split('\n');
lines.forEach(line => {
if (line.includes('ERROR')) {
console.log(`\x1b[31m${line}\x1b[0m`); // قرمز
} else if (line.includes('WARN')) {
console.log(`\x1b[33m${line}\x1b[0m`); // زرد
} else if (line.includes('SUCCESS')) {
console.log(`\x1b[32m${line}\x1b[0m`); // سبز
} else {
console.log(line);
}
});
});
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 5: نمایش لاگها و شمارش خطاها
(async () => {
const k3 = new K3Core();
try {
const logs = await k3.containerCore.getContainerLogs('service', {
number: 200
});
let errorCount = 0;
let warningCount = 0;
console.log('Log Analysis:');
console.log(`Total entries: ${logs.length}`);
logs.forEach((entry) => {
if (entry.message.includes('ERROR')) errorCount++;
if (entry.message.includes('WARN')) warningCount++;
});
console.log(`Errors: ${errorCount}`);
console.log(`Warnings: ${warningCount}`);
if (errorCount > 0) {
console.log('\nError entries:');
logs.filter(e => e.message.includes('ERROR')).forEach(entry => {
console.log(`[${entry.timestamp}] ${entry.message.substring(0, 80)}`);
});
}
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 6: صادرات لاگها به فایل
const fs = require('fs');
const path = require('path');
(async () => {
const k3 = new K3Core();
try {
const logs = await k3.containerCore.getContainerLogs('app', {});
// ایجاد فایل خروجی
const timestamp = new Date().toISOString().replace(/:/g, '-');
const filename = `logs-${timestamp}.txt`;
const filepath = path.join('/tmp', filename);
let content = `Container Logs Export\n`;
content += `Generated: ${new Date().toISOString()}\n`;
content += `Total Entries: ${logs.length}\n`;
content += `${'='.repeat(80)}\n\n`;
logs.forEach((entry) => {
content += `[${entry.timestamp}]\n`;
content += entry.message + '\n';
content += '-'.repeat(40) + '\n';
});
fs.writeFileSync(filepath, content);
console.log(`Logs exported to: ${filepath}`);
} catch (error) {
console.log(error.createFullMessage());
}
})();
مثال 7: دریافت لاگهای اخیر و نمایش realtime
(async () => {
const k3 = new K3Core();
let lastTimestamp = null;
const displayNewLogs = async () => {
try {
const logs = await k3.containerCore.getContainerLogs('app', {});
if (logs.length === 0) {
console.log('No logs available');
return;
}
let newEntries = logs;
if (lastTimestamp) {
newEntries = logs.filter(entry =>
new Date(entry.timestamp) > new Date(lastTimestamp)
);
}
if (newEntries.length > 0) {
console.log(`\n[${new Date().toISOString()}] New entries:`);
newEntries.forEach((entry) => {
console.log(`[${entry.timestamp}]`);
console.log(entry.message);
});
lastTimestamp = logs[logs.length - 1].timestamp;
}
} catch (error) {
console.log('Error fetching logs:', error.message);
}
};
// هر 5 ثانیه
setInterval(displayNewLogs, 5000);
// اولین بار بلافاصله
await displayNewLogs();
})();
مثال 8: دریافت لاگ و بررسی وضعیت
(async () => {
const k3 = new K3Core();
const containerId = 'monitor-service';
try {
// Step 1: بررسی کانتینر
const inspect = await k3.containerCore.inspectContainer(containerId);
console.log(`Container: ${inspect.name}`);
console.log(`Status: ${inspect.state?.running ? 'Running' : 'Stopped'}`);
console.log(`PID: ${inspect.state?.pid}`);
// Step 2: دریافت لاگهای اخیر
try {
const logs = await k3.containerCore.getContainerLogs(containerId, {
number: 30
});
console.log(`\nRecent logs (${logs.length} entries):`);
// آخرین entry
if (logs.length > 0) {
const lastEntry = logs[logs.length - 1];
console.log(`Last update: ${lastEntry.timestamp}`);
console.log(`Message: ${lastEntry.message.split('\n')[0]}`);
}
// شمارش خطاها
const errorCount = logs.filter(e =>
e.message.includes('ERROR')
).length;
if (errorCount > 0) {
console.log(`\n⚠️ Found ${errorCount} errors`);
} else {
console.log(`\n✅ No errors found`);
}
} catch (error) {
if (error.type === 'NOT_FOUND') {
console.log('No logs available yet (container just started?)');
} else {
console.log('Error fetching logs:', error.message);
}
}
} catch (error) {
console.log(error.createFullMessage());
}
})();
الگوهای خطا و راهنمای حل
الگو 1: کانتینر یافت نشد
خطا: ContainerNotFound (404)
راهنمای حل:
try {
const logs = await k3.containerCore.getContainerLogs('unknown-container', {});
} catch (error) {
if (error.type === 'NOT_FOUND') {
console.log('Container not found');
const containers = await k3.containerCore.listContainers({ all: true });
console.log('Available containers:');
containers.forEach(c => console.log(` - ${c.name} (${c.id})`));
} else {
console.log(error.createFullMessage());
}
}
الگو 2: لاگ فایل موجود نیست
خطا: ContainerRecord (404)
راهنمای حل:
try {
const logs = await k3.containerCore.getContainerLogs('fresh-container', {});
} catch (error) {
if (error.message.includes('ENOENT') || error.message.includes('no such file')) {
console.log('Container has not produced any logs yet');
// کانتینر را شروع کنید
const inspect = await k3.containerCore.inspectContainer('fresh-container');
if (!inspect.state?.running) {
console.log('Starting container to generate logs...');
await k3.containerCore.startContainer('fresh-container', {});
// صبر برای تولید لاگ
await new Promise(resolve => setTimeout(resolve, 2000));
// دوباره تلاش کنید
const logs = await k3.containerCore.getContainerLogs('fresh-container', {});
console.log('Logs retrieved after start');
}
} else {
console.log(error.createFullMessage());
}
}
الگو 3: فیلتر کردن لاگهای خطا
راهنمای حل:
const getErrorLogs = async (containerId) => {
try {
const logs = await k3.containerCore.getContainerLogs(containerId, {
number: 500
});
const errors = logs.filter(entry =>
entry.message.includes('ERROR') ||
entry.message.includes('Exception') ||
entry.message.includes('Failed')
);
return errors;
} catch (error) {
console.log('Error fetching logs:', error.message);
return [];
}
};
const errors = await getErrorLogs('app');
console.log(`Found ${errors.length} error entries`);
errors.forEach(entry => {
console.log(`[${entry.timestamp}] ${entry.message}`);
});
الگو 4: نمایش لاگهای real-time
راهنمای حل:
class LogTail {
constructor(containerId, interval = 3000) {
this.containerId = containerId;
this.interval = interval;
this.lastCount = 0;
}
async start(k3) {
console.log(`Tailing logs for ${this.containerId}...`);
console.log('Press Ctrl+C to stop\n');
this.intervalId = setInterval(async () => {
try {
const logs = await k3.containerCore.getContainerLogs(this.containerId, {});
const newCount = logs.length;
if (newCount > this.lastCount) {
const newEntries = logs.slice(this.lastCount);
newEntries.forEach(entry => {
console.log(`[${entry.timestamp}] ${entry.message}`);
});
this.lastCount = newCount;
}
} catch (error) {
if (error.message.includes('ENOENT')) {
console.log('(Waiting for logs...)');
} else {
console.error('Error:', error.message);
}
}
}, this.interval);
}
stop() {
if (this.intervalId) {
clearInterval(this.intervalId);
console.log('\nLog tail stopped');
}
}
}
const tail = new LogTail('my-app', 2000);
await tail.start(k3);
الگو 5: تحلیل لاگها
راهنمای حل:
const analyzeLogs = async (containerId) => {
try {
const logs = await k3.containerCore.getContainerLogs(containerId, {
number: 1000
});
const analysis = {
total: logs.length,
errors: 0,
warnings: 0,
info: 0,
timestamps: []
};
logs.forEach(entry => {
analysis.timestamps.push(entry.timestamp);
const msg = entry.message.toLowerCase();
if (msg.includes('error')) analysis.errors++;
else if (msg.includes('warn')) analysis.warnings++;
else analysis.info++;
});
return analysis;
} catch (error) {
console.log('Analysis failed:', error.message);
return null;
}
};
const analysis = await analyzeLogs('app');
console.log('Log Analysis:');
console.log(` Total: ${analysis.total}`);
console.log(` Errors: ${analysis.errors}`);
console.log(` Warnings: ${analysis.warnings}`);
console.log(` Info: ${analysis.info}`);
نکات عملی
-
Log Format:
- Timestamp:
Mon Jan 01 12:30:45 UTC 2025 - Message: یک یا چند خط متن
- Timestamp:
-
Filter by Number:
- پیشفرض: تمام entries
- مثال:
number: 10آخرین 10 entry
-
Parsing:
- Timestamps regex:
^(Mon|Tue|...|Sun)\s+[A-Z][a-z]{2}\s+\d{1,2}... - Multi-line messages: lines بعد از timestamp
- Timestamps regex:
-
Performance:
- برای لاگهای بزرگ از
numberاستفاده کنید - تعداد زیاد entries صبورطلب است
- برای لاگهای بزرگ از
-
Log Locations:
- Log path:
/var/lib/k3/containers/<hash>/logs/K3.log - Exec log:
/var/lib/k3/containers/<hash>/log.jsonl
- Log path:
-
Error Handling:
- ENOENT = container has no logs yet
- Container must exist in DB
- Log file must be readable
-
Future Features:
follow: trueبرای real-time (TODO)filter: "regex"برای جستجو (TODO)- Stream output instead of array (TODO)
دنباله عملیات
- Resolve container ID/name
- Fetch logs from container manager
- Check for ENOENT errors
- Parse timestamp lines (regex match)
- Collect message lines (multi-line support)
- Build log entries array
- Filter by number (slice last N)
- Return entries
- Log operation
مرجع سریع
| وضعیت | کد | توضیح |
|---|---|---|
| موفق | 200 | لاگها دریافت شدند |
| هیچ لاگی | 200 | آرایه خالی |
| یافت نشد | 404 | ContainerNotFound |
| لاگ نیست | 404 | ContainerRecord |
| خطای DB | 500 | ResolveContainerName |
| خطای FS | 500 | GenericFailure |
موارد استفاده
Debugging
// بررسی خطاهای کانتینر
const logs = await getContainerLogs('app', { number: 50 });
const errors = logs.filter(l => l.message.includes('ERROR'));
Audit & Reporting
// صادرات لاگ برای گزارش
const logs = await getContainerLogs('app', {});
fs.writeFileSync('audit.log', formatLogs(logs));
Troubleshooting
// بررسی performance issues
const logs = await getContainerLogs('slow-app', { number: 200 });
نسخه: 1.3
تاریخ آپدیت: 9 آذرماه ۱۴۰۴
تیم توسعه: K3 Development Team