6.3 KiB
Executable File
6.3 KiB
Executable File
Logging Audit Guide for Hectic
This guide provides a systematic approach to auditing and improving logging in existing functions of the Hectic library.
Checklist for Function Audit
1. Basic Logging Check
- Function has entry logging (DEBUG or TRACE level)
- Function has result/exit logging
- Failures and errors are logged with appropriate levels (WARN or EXCEPTION)
- Intermediate steps are logged at TRACE or DEBUG level
- Successful operation completions are logged at LOG level
2. Level Consistency Check
LOG_LEVEL_TRACEis used for detailed execution trackingLOG_LEVEL_DEBUGis used for significant internal stepsLOG_LEVEL_LOGis used for important operational events and successful operation completionsLOG_LEVEL_INFOis used rarely, only for user-critical eventsLOG_LEVEL_NOTICEis used very rarely, almost not needed for a low-level libraryLOG_LEVEL_WARNis used for recoverable problemsLOG_LEVEL_EXCEPTIONis used only for critical errors
3. Message Formatting Check
- Messages start with a domain prefix (PARSE:, ALLOC:, FORMAT:, etc.)
- Message structure follows the pattern "Action: object (details)"
- Messages contain sufficient context for understanding (pointers, sizes, values)
- Messages don't contain redundant information
- Pointers use %p format
- Sizes use %zu format
- Strings use length limitation when necessary (%.20s)
- NULL pointer checks are added before using pointers in logs
Logging Level Usage Rules
TRACE
- Function calls and exits
- Detailed loop iteration information
- Variable values during execution
- Any detailed debugging information
DEBUG
- Entries to public API functions
- Resource allocation and deallocation
- Key algorithm steps
- Data processing details
LOG
- Successful component initialization
- Completion of significant operations
- State changes important for operation
- Key business logic points
INFO (use rarely!)
- Library startup and shutdown
- Version and configuration information
- Extremely important events visible to users
- Large operations requested by users
NOTICE (almost never use)
- Events that users should pay attention to
- Significant planned actions
WARN
- Unexpected but handled errors
- Edge cases
- Warnings about potential problems
- Use of deprecated APIs
EXCEPTION
- Serious errors affecting system operation
- Data integrity violations
- Resource exhaustion
- Critical security failures
Audit and Update Process
Step 1: Function Analysis
-
Determine the function type:
- Initialization/resource management function
- Data processing function
- Utility function
- Other
-
Identify key logging points:
- Function entry
- Parameter checks
- Main processing steps
- Error conditions
- Function exit
Step 2: Update Planning
- Create a list of necessary logs at each level
- Determine the right prefixes for each message type
- Prepare detailed messages with necessary context
- Ensure parameter checks are logged before use
Step 3: Implementing Changes
- Add/update function entry logging
- Add/update input parameter checks
- Update intermediate step logging
- Add/update error condition logging
- Add/update result logging
Step 4: Testing
- Check message output correctness
- Verify proper level usage
- Check that all necessary information is included in logs
- Compare with other already updated functions for consistency
Examples for Typical Functions
Memory Allocation Function:
void* memory_function__(const char *file, const char *func, int line, size_t size) {
// Function entry
raise_message(LOG_LEVEL_DEBUG, file, func, line,
"ALLOC: Requesting memory allocation (size: %zu bytes)", size);
// Parameter check
if (size == 0) {
raise_message(LOG_LEVEL_WARN, file, func, line,
"ALLOC: Zero-sized memory allocation requested");
return NULL;
}
// Memory allocation
void *ptr = malloc(size);
if (!ptr) {
raise_message(LOG_LEVEL_EXCEPTION, file, func, line,
"ALLOC: Memory allocation failed (requested: %zu bytes)", size);
return NULL;
}
// Result
raise_message(LOG_LEVEL_LOG, file, func, line,
"ALLOC: Memory allocated successfully (address: %p, size: %zu bytes)",
ptr, size);
return ptr;
}
Data Conversion Function:
char* convert_function__(const char *file, const char *func, int line,
const void *input, size_t input_size) {
// Function entry
raise_message(LOG_LEVEL_DEBUG, file, func, line,
"CONVERT: Starting data conversion (input: %p, size: %zu)",
input, input_size);
// Parameter check
if (!input) {
raise_message(LOG_LEVEL_WARN, file, func, line,
"CONVERT: NULL input provided");
return NULL;
}
if (input_size == 0) {
raise_message(LOG_LEVEL_WARN, file, func, line,
"CONVERT: Zero input size provided");
return NULL;
}
// Processing start
raise_message(LOG_LEVEL_TRACE, file, func, line,
"CONVERT: Processing input data...");
// Processing...
// Result
char *result = NULL; // conversion result
if (!result) {
raise_message(LOG_LEVEL_WARN, file, func, line,
"CONVERT: Conversion failed");
return NULL;
}
raise_message(LOG_LEVEL_LOG, file, func, line,
"CONVERT: Data conversion completed successfully (result: %p)", result);
return result;
}
Update Priorities
Recommended order for updating functions:
- Memory management functions (
arena_*) - Parsing functions (
json_parse_*) - Formatting functions (
json_to_string_*) - Data processing functions (
slice_*) - Utility functions
Conclusion
Consistent application of these recommendations to functions in the library will significantly improve logging quality and facilitate debugging and code maintenance in the future.