پرش به مطلب اصلی

نمایش لاگ‌های خروجی کانتینر

لاگ‌های خروجی کانتینر را با فیلتر و پارسینگ timestamp نمایش می‌دهد.


🧩 دستور کلی

async getContainerLogs(containerId, options = {})

شرح عملکرد

این متد لاگ‌های خروجی کانتینر را بازیابی می‌کند. شامل:

  • تأیید کانتینر موجود است
  • دریافت لاگ‌های raw از container manager
  • پارسینگ timestamps (روز هفته، تاریخ، ساعت)
  • سازماندهی entries با timestamp و message
  • فیلتر کردن بر اساس تعداد آخرین entries
  • logging عملیات

مهم: لاگ‌های کانتینر در فایل متنی ذخیره می‌شوند. اگر فایل موجود نباشد، خطای 404 برگشت داده می‌شود.


ورودی‌ها

پارامترنوعاجباریتوضیح
containerIdStringبلهشناسه یا نام کانتینر
optionsObjectبلهگزینه‌های لاگ
options.numberNumberخیرتعداد آخرین entries (پیش‌فرض: همه)
options.followBooleanخیردنبال کردن زنده (future feature)
options.filterStringخیرفیلتر بر اساس کلیدواژه (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}`);

نکات عملی

  1. Log Format:

    • Timestamp: Mon Jan 01 12:30:45 UTC 2025
    • Message: یک یا چند خط متن
  2. Filter by Number:

    • پیش‌فرض: تمام entries
    • مثال: number: 10 آخرین 10 entry
  3. Parsing:

    • Timestamps regex: ^(Mon|Tue|...|Sun)\s+[A-Z][a-z]{2}\s+\d{1,2}...
    • Multi-line messages: lines بعد از timestamp
  4. Performance:

    • برای لاگ‌های بزرگ از number استفاده کنید
    • تعداد زیاد entries صبورطلب است
  5. Log Locations:

    • Log path: /var/lib/k3/containers/<hash>/logs/K3.log
    • Exec log: /var/lib/k3/containers/<hash>/log.jsonl
  6. Error Handling:

    • ENOENT = container has no logs yet
    • Container must exist in DB
    • Log file must be readable
  7. Future Features:

    • follow: true برای real-time (TODO)
    • filter: "regex" برای جستجو (TODO)
    • Stream output instead of array (TODO)

دنباله عملیات

  1. Resolve container ID/name
  2. Fetch logs from container manager
  3. Check for ENOENT errors
  4. Parse timestamp lines (regex match)
  5. Collect message lines (multi-line support)
  6. Build log entries array
  7. Filter by number (slice last N)
  8. Return entries
  9. Log operation

مرجع سریع

وضعیتکدتوضیح
موفق200لاگ‌ها دریافت شدند
هیچ لاگی200آرایه خالی
یافت نشد404ContainerNotFound
لاگ نیست404ContainerRecord
خطای DB500ResolveContainerName
خطای FS500GenericFailure

موارد استفاده

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