ในโปรแกรมขนาดใหญ่ C ประยุกต์ การทําเล็บเป็นเครื่องมือสําคัญในการดีบั๊ก การติดตาม และรักษาสุขภาพของระบบ ในขณะที่พื้นฐาน [FLT: 0] ข้อความหรือไลบรารีต่าง ๆ เช่น [FLT: 1] อาจเพียงพอกับโครงการขนาดเล็ก มันมักจะสั้นลงเมื่อประสิทธิภาพ, ความยืดหยุ่น, และความง่ายกลายเป็นความต้องการที่ยืดหยุ่น, ระบบการคัดสรรที่ปรับแต่งให้เข้ากับระบบของคุณ การตัดส่วนควบคุมระดับการทํางานของคุณให้แม่นยํากว่าระดับการตกแต่ง, การตกแต่ง, และโครงสร้างความปลอดภัย บทความนี้สามารถดําเนินผ่านการออกแบบและการทํางานอย่างมีประสิทธิภาพในระบบ การทําการผลิตที่มีประสิทธิภาพใน C, และระบบปฏิบัติการที่ดีที่สุด สําหรับการใช้งานที่ดี และระบบปฏิบัติการที่ดีที่สุด
ทําไม จึง สร้าง ระบบ การ จด บันทึก ที่ กําหนด ไว้
กลไกการคัดแยกมาตรฐาน เช่น หรือ POSIX API มักขาดความจุสีและประสิทธิภาพที่ต้องใช้โดยโปรแกรมขนาดใหญ่ ตัวบันทึกกําหนดเองเสนอ:
- [FLT: 0] ผลงานประกอบ: หลีกการวางผังและรูปแบบที่ไม่จําเป็น เมื่อระดับปูมบันทึกถูกระงับ
- [FLT: 0] การฟอร์แมตแบบ flickble: การจัดเวลาตามเวลา, igns sports, และโมดูลเพิ่มเติมความคมชัดของปูมบันทึกและสวรรคต
- [FLT: 0] ควบคุมระดับ: เปิด/discan log at period time โดยไม่คอมไพล์ใหม่
- [FLT: 0] ปลายทางที่เงียบสนิท : เขียนไปที่คอนโซล, ไฟล์, ฐานเครือข่าย, หรือระบบติดตามภายนอกพร้อมกัน
- [FLT: 0]. ความปลอดภัย: ใช้สลิตซ์หรืออะตอมดําเนินการเพื่อป้องกันการส่งออกแบบข้ามภาคต่อในโปรแกรมหลายฉบับ.
การ ออก แบบ แกน หลัก
การ ตัดสิน ใจ เหล่า นี้ จะ เปลี่ยน ทุก สิ่ง ตั้ง แต่ การ ออก แบบ เอ พี ไอ มา เป็น การ แสดง เวลา.
ระดับปูมบันทึก
กําหนดระดับความเข้มที่โยงไปยังความต้องการของโปรแกรม อยู่ในระดับทั่วไปที่รวม [FLT: 4] [FLT: 5] [FLT: 6] [FLT: 6] [FLT: 7]] [FLT: 8] และ[FT: 9] ใช้ [FTT: 10] เพื่อรับประกันความปลอดภัย แต่ละระดับควรมีขีดจํากัดต่ําที่สุด; ขอบเขตการวางจําหน่ายด้านล่างนั้นถูกลดต่ําลงในการผลิต
ปูมบันทึกปลายทาง
ลอง พิจารณา ว่า จะ เขียน บันทึก เสียง ไว้ ที่ ไหน.
- [FLT: 0] คอนเซเล (FLT:1] - สําหรับการพัฒนาและดีบั๊กอย่างรวดเร็ว
- [FLT: 0]. file - ด้วยการหมุนและโค้งเพื่อจัดการพื้นที่ดิสก์.
- [FLT: 0]. Syslog - สําหรับระบบการไม้แบบกลาง
- [FLT: 0] Network – UDP หรือ TCP ฐานสําหรับรังไข่ระยะไกล (e.g. Graylog, ElK สแต็ก).
ตัวล็อกที่ถูกออกแบบอย่างดี ใช้เครื่องหมาย นามธรรมที่ทําให้คุณได้เพิ่มหรือลบปลายทางที่ทํางานอยู่
การ จัด เรียง และ การ ประชุม ภาค
เลือกรูปแบบปูมบันทึกก่อนในการคงความสอดคล้องกัน รูปแบบทั่วไปคือ จับเวลา, ระดับปูมบันทึก, ต้นฉบับ, ชื่อโมดูล, และข้อความ รูปแบบโครงสร้างเช่น Json แบบปรับเทียบข้อมูลอัตโนมัติ แต่เพิ่มค่าต่าง ๆ เพื่อประสิทธิภาพ ให้ใช้ตัวแปลงที่คงที่ของช่องข้อมูล (เช่น space, Place, หรือแท็บ) และหลีกเลี่ยงการระบุตําแหน่งหน่วยความจําแบบไม่ตายตัว ในพาธที่ร้อน
ความปลอดภัยของเธรด
ในโปรแกรมหลายแบบ การเขียนแบบถอดเสียบ สามารถผลิตผลลัพธ์ที่ออกมาได้ โปรดใช้ [FLT: 11] (บนระบบ POSIX) หรือส่วนวิกฤต (บนวินโดวส์) รอบ ๆ การปฏิบัติการ I/O ที่อยู่จริง สําหรับระดับสูงกว่า ให้พิจารณาคิวแบบไม่ใส่กุญแจ หรือ protoffffuls ที่ถูกกดไว้เป็นระยะ ๆ
การ ทํา ให้ ลอกเกอร์ พื้น ฐาน สําเร็จ
เริ่ม ด้วย การ จัด เรียง ข้อ ความ ที่ เรียบ ง่าย ซึ่ง ครอบ คลุม สิ่ง จําเป็น: ระดับ การ บันทึก, การ ชดเชย เวลา, และ การ สร้าง ข้อ ความ.
ฟังก์ชันของปูมบันทึกระดับอีนูมและตัวช่วยเหลือ
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <pthread.h>
typedef enum {
LOG_LEVEL_TRACE,
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR,
LOG_LEVEL_FATAL
} LogLevel;
static const char* level_strings[] = {
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};
static LogLevel g_min_level = LOG_LEVEL_INFO;
static pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
การฟอร์แมตจดหมาย
ฟังก์ชัน Dolf ของระบบหลักจะใช้ [FLT: 13] เพื่อฟอร์แมตจดหมายอย่างปลอดภัย ส่วนบัฟเฟอร์แบบคงที่ จะหลีกเลี่ยงการวางกองเรียงในเส้นทางที่ร้อนจัด แต่โปรดระวังการปล่อยบัฟเฟอร์ให้ไหลมาทางจดหมายที่ยาวมาก
void log_message(LogLevel level, const char* file, int line, const char* func, const char* format, ...) {
if (level < g_min_level) return;
time_t now = time(NULL);
struct tm* tm_info = localtime(&now);
char time_buf[20];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm_info);
pthread_mutex_lock(&g_log_mutex);
// Write header
fprintf(stdout, "[%s] [%s] [%s:%d %s] ", time_buf, level_strings[level], file, line, func);
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fprintf(stdout, "\n");
fflush(stdout); // Ensure immediate output for debugging
pthread_mutex_unlock(&g_log_mutex);
}
เพื่อความสะดวก ให้กําหนดแมโครที่จับแฟ้มต้นทางและบรรทัดโดยอัตโนมัติ:
#define LOG_TRACE(...) log_message(LOG_LEVEL_TRACE, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define LOG_DEBUG(...) log_message(LOG_LEVEL_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__)
// ... similar for INFO, WARN, ERROR, FATAL
ตัวอย่างการใช้งาน:
int main() {
LOG_INFO("Application started on port %d", 8080);
LOG_WARN("Disk usage exceeding %.1f%%", 85.3);
LOG_ERROR("Failed to open file: %s", "config.dat");
return 0;
}
กําลังเพิ่มการแสดงผลและการหมุนแฟ้ม
การแสดงผลแบบคอนโซลนี้มีประโยชน์มากระหว่างการพัฒนา แต่ระบบการผลิตต้องการปูมบันทึกแบบถาวร เพิ่มแฟ้มในแฟ้ม ที่เขียนไปยังชุดการหมุนของแฟ้มปูมบันทึก
กําลังบันทึกแฟ้ม
ขยายตัวติดตามการทํางานด้วยตัวชี้ของแฟ้ม คุณสามารถจะถอดรหัสพาธหรือทําให้มันสามารถปรับแต่งได้ โดยตัวเข้ารหัสเดียวกันนี้ จะใช้การป้องกันการเขียนแบบ SSLX ตัวเดียวกัน
static FILE* g_log_file = NULL;
int log_init_file(const char* path) {
g_log_file = fopen(path, "a");
return (g_log_file != NULL) ? 0 : -1;
}
void log_message_file(LogLevel level, const char* file, int line, const char* func, const char* format, ...) {
// Same timestamp and header logic, but write to g_log_file
// ...
}
ลวดลายStencils
เพื่อป้องกันแฟ้มปูมบันทึกจากการบริโภคพื้นที่ดิสก์ทั้งหมด ให้ทําการหมุนแบบพอดีโดยใช้ขนาดแฟ้ม, วันที่, หรือทั้ง 2 แบบ กลยุทธ์ง่าย ๆ:
- แทร็กเสียงขนาดแฟ้มปัจจุบัน โดยการตรวจสอบ [FLT: 18] หลังจากแต่ละเขียน (หรือช่วงเวลา)
- เมื่อแฟ้มเกินขีด จํากัด (เช่น 100 MB) เปลี่ยนชื่อ ( ⁇ ] จากนั้นบีบแฟ้มเก่า ๆ และเปิดใหม่.
- คงจํานวนของแฟ้มที่หมุนได้สูงสุด; ลบแฟ้มที่เก่าที่สุด
โครงสร้างตัวอย่าง:
void log_rotate_if_needed() {
if (g_log_file && ftell(g_log_file) > MAX_LOG_SIZE) {
fclose(g_log_file);
// Rename and compress logic
g_log_file = fopen(LOG_PATH, "a");
}
}
การ จับ ปลา อย่าง แยบยล เพื่อ ได้ ผล งาน
I/O โดยตรงในเส้นทางที่ร้อน สามารถบล็อกเธรดและประสิทธิภาพการเสื่อมค่าได้ การลบข้อความแบบย่อ (Assychronous decouples) จากดิสก์หรือเครือข่ายการเขียนโดยใช้คิวของผู้ผลิต supercumer
รูปแบบตัวผลิต
ใช้บัฟเฟอร์ของแหวนแบบขอบ หรือคิวแบบล็อค (เช่น [FLT: 23] หรือรายการที่เชื่อมโยงแบบง่าย ๆ กับ Slutx) เพื่อจัดเก็บข้อความปูมบันทึก โดยมีเธรดที่อุทิศแล้วกดไลซ์คิว
ผลประโยชน์:
- เครือข่ายโปรแกรมไม่เคยรอ I/O
- สามารถจัดการจดหมายที่ทิ้งแล้วได้อย่างนุ่มนวล (เช่น เพิ่มตัวนับ)
- การเขียนของแบทชิงลดการโทรออกของระบบ
การ ชด ใช้
#define QUEUE_SIZE 8192
static char g_log_queue[QUEUE_SIZE][MAX_LOG_LINE];
static volatile int g_queue_head = 0, g_queue_tail = 0;
static pthread_mutex_t g_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_queue_notify = PTHREAD_COND_INITIALIZER;
void push_log(const char* logline) {
pthread_mutex_lock(&g_queue_mutex);
// Copy and advance head (ring buffer)
strncpy(g_log_queue[g_queue_head], logline, MAX_LOG_LINE);
g_queue_head = (g_queue_head + 1) % QUEUE_SIZE;
pthread_cond_signal(&g_queue_notify);
pthread_mutex_unlock(&g_queue_mutex);
}
void* log_flush_thread(void* arg) {
while (1) {
pthread_mutex_lock(&g_queue_mutex);
while (g_queue_head == g_queue_tail)
pthread_cond_wait(&g_queue_notify, &g_queue_mutex);
// Dequeue and write to file/console
char buffer[MAX_LOG_LINE];
strncpy(buffer, g_log_queue[g_queue_tail], MAX_LOG_LINE);
g_queue_tail = (g_queue_tail + 1) % QUEUE_SIZE;
pthread_mutex_unlock(&g_queue_mutex);
// Perform I/O (protected by the same file mutex)
fputs(buffer, g_log_file);
}
return NULL;
}
คุณสมบัติเพิ่มเติม
เมื่อ ระบบ พื้น ฐาน ดําเนิน งาน แล้ว ขอ พิจารณา การ เสริม การ ใช้ ประโยชน์ จาก การ ใช้ มาก ขึ้น.
การติดตามแบบโครงสร้าง (Json)
ปูมบันทึกแบบโครงสร้างนี้ จะช่วยใช้ในการวิเคราะห์อัตโนมัติ ใช้ไลบรารีแบบ Light Json เช่น [FLT: 0] cJson[FLT: 1) เพื่อสร้างวัตถุ รูปแบบของ:
{"timestamp":"2025-03-20T10:15:30Z","level":"ERROR","module":"auth","message":"Login failed","user":"john"}
ขณะ ที่ กริยา กริยา รูป แบบ นี้ ผนวก เข้า กับ เครื่อง มือ อย่าง เช่น การ ค้นคว้า และ การ โบก มือ.
การบันทึกระยะไกลผ่านทาง Syslog หรือเครือข่าย
สําหรับระบบที่แจกจ่ายไป ปูมบันทึกการส่งต่อไปยังเครื่องมือรวบรวมข้อมูลแบบ POSSIX [FLT: 26] ฟังก์ชัน ([FLT: 0] หน้ากล้อง [FLT: 1) เป็นรูปแบบตรง แต่จํากัด. ทางเลือกอื่น คือ ส่งข้อมูลยูดีพีแกรมไปใช้ Graylog หรือ Logstash poting โดยใช้ฐานรากดิบ
แฟ้มการปรับแต่ง
อนุญาตให้ผู้ดําเนินการทําการแก้ไขค่าพารามิเตอร์ของปูมบันทึกโดยไม่ต้องทําการปรับปรุงใหม่: ระดับปูมบันทึก, พาธของแฟ้ม, ขนาดการหมุน, และปลายทางที่ส่งออกไป โดยจัดทําแฟ้ม INIT: 27 แบบง่าย ๆ หรือใช้ตัวแปรแวดล้อม ซึ่งการปรับแต่งสามารถเรียกใหม่ได้โดยผ่านทางสัญญาณ (เช่น [FLT: 27]
การ ฝึก อบรม ที่ ดี ที่ สุด และ หลุม พราง
หลีก เลี่ยง ความ ผิด พลาด ทั่ว ไป ซึ่ง บ่อน ทําลาย คุณค่า ของ การ ทํา ไม้.
ประมวลผล
การบันทึกไม่ควรกลายเป็นการแขวนกระดาษ การตรวจสอบระดับปูมบันทึกก่อนทําการฟอร์แมตอาร์กิวเมนต์เสมอ ใช้ kmagna ที่ประเมินระดับได้อย่างรวดเร็ว หลีกเลี่ยง [FLT: 28] ในเส้นทางวิกฤต ใช้กล่องบัฟเฟอร์สแต็กแทน
ความ ห่วงใย เรื่อง ความ ปลอด ภัย
ห้ามบันทึกข้อมูลไวตาบ เช่น รหัสผ่าน, หมายเลขบัตรเครดิต หรือข้อมูลส่วนตัว. เปรียบเทียบข้อมูลผู้ใช้ และพิจารณาการตกแต่งช่องข้อมูลใหม่ในการผลิต. เช่นเดียวกัน ป้องกันแฟ้มปูมบันทึกจากการเข้าใช้งานที่ไม่ได้รับอนุญาต.
ความต่อเนื่องของโมดูล
ตั้งค่าการประชุมการคัดสรรแบบบริษัทแบบทั่วไป ใช้โมดูลแบบพิเศษ (เช่น [FLT: 29], [FLT: 30]] และรูปแบบมาตรฐานเวลา (UTC เหมาะกับระบบกระจายข้อมูล) เอกสารรูปแบบปูมบันทึกเพื่อให้ทีมปฏิบัติการสามารถวิเคราะห์ได้
รูปแบบการวน
ระบบการคัดแยกที่กําหนดเองใน C ให้ความยืดหยุ่นและประสิทธิภาพที่จําเป็นสําหรับโปรแกรมขนาดใหญ่ โดยเริ่มจากการออกแบบที่ครอบคลุมระดับการปูมบันทึก, ยุบ, ความปลอดภัยของเธรด, และรูปแบบรูปแบบต่าง ๆ คุณสามารถค่อยๆเพิ่มคุณสมบัติขั้นสูงเช่น การขยายภาพ, การวางแผงแบบโครงสร้าง, และการทํางานแบบระยะไกล ตัวอย่างในบทความนี้ทําหน้าที่เป็นรากฐาน -- ร่วมกับสภาพแวดล้อมเฉพาะของคุณ และมักจะวัดค่าของเงื่อนไขต่าง ๆ ด้วยการใช้อย่างรอบคอบ การนําร่องจะกลายเป็นการมีประสิทธิภาพมากกว่าการทํางาน สําหรับอ่านเพิ่มเติม [TLF] ดูเพิ่มที่: [F] หน้า [FTL] หน้า [F] หน้า 1 [TL] และบันทึกมาตรฐาน: CIL].