fix: hectic C: impruve logging guidelines
This commit is contained in:
153
package/c/hectic/docs/logging.md
Executable file
153
package/c/hectic/docs/logging.md
Executable file
@@ -0,0 +1,153 @@
|
||||
# Hectic Library Logging System
|
||||
|
||||
This document provides guidelines on how to use the logging system in the Hectic library effectively.
|
||||
|
||||
## Log Levels
|
||||
|
||||
The Hectic library implements a graduated severity-based logging system with the following levels (from lowest to highest severity):
|
||||
|
||||
### TRACE
|
||||
**Purpose**: Most detailed information for in-depth debugging
|
||||
- Use for: Deep diagnostic details, function entry/exit, variable dumps
|
||||
- Visibility: Development environments only
|
||||
- Performance Impact: High
|
||||
- Example: `raise_trace("Entering function with value=%d, ptr=%p", value, ptr);`
|
||||
|
||||
### DEBUG
|
||||
**Purpose**: Detailed information useful during development
|
||||
- Use for: Development-time debugging, showing variable states, internal flows
|
||||
- Visibility: Development and debugging environments
|
||||
- Performance Impact: Medium-High
|
||||
- Example: `raise_debug("Buffer allocated with size %zu bytes at %p", size, buffer);`
|
||||
|
||||
### LOG
|
||||
**Purpose**: General operational events
|
||||
- Use for: Runtime events worth logging but not requiring attention
|
||||
- Visibility: Always written to logs, useful for auditing/diagnostics
|
||||
- Performance Impact: Medium
|
||||
- Example: `raise_log("Processing file %s, size: %zu bytes", filename, file_size);`
|
||||
|
||||
### INFO
|
||||
**Purpose**: Informational messages highlighting progress
|
||||
- Use for: Normal but noteworthy events, state changes, startup/shutdown events
|
||||
- Visibility: Visible to client applications if configured
|
||||
- Performance Impact: Low-Medium
|
||||
- Example: `raise_info("Connection established to %s, session ID: %s", host, session_id);`
|
||||
|
||||
### NOTICE
|
||||
**Purpose**: More important events than INFO, but not warnings
|
||||
- Use for: Important state changes, significant operations, configuration changes
|
||||
- Visibility: Displayed to client by default
|
||||
- Performance Impact: Low
|
||||
- Example: `raise_notice("Switching to backup server due to high load");`
|
||||
|
||||
### WARN
|
||||
**Purpose**: Potential problems that don't prevent normal operation
|
||||
- Use for: Unexpected behaviors, deprecated feature usage, recoverable errors
|
||||
- Visibility: Alerts both client and server logs
|
||||
- Performance Impact: Low
|
||||
- Example: `raise_warn("API call retry limit (%d) reached for endpoint %s", retries, endpoint);`
|
||||
|
||||
### EXCEPTION
|
||||
**Purpose**: Serious errors requiring immediate attention
|
||||
- Use for: Critical failures, data loss risks, business rule violations
|
||||
- Visibility: Highest priority, often leads to operation termination
|
||||
- Performance Impact: Low
|
||||
- Example: `raise_exception("Failed to open database: %s", error_msg);`
|
||||
|
||||
## Setting the Log Level
|
||||
|
||||
You can control the verbosity of logs in three ways:
|
||||
|
||||
1. **Environment Variable**: Set `LOG_LEVEL` environment variable
|
||||
```sh
|
||||
export LOG_LEVEL=DEBUG
|
||||
```
|
||||
|
||||
2. **Programmatically**: Use the `logger_level()` function
|
||||
```c
|
||||
logger_level(LOG_LEVEL_DEBUG);
|
||||
```
|
||||
|
||||
3. **Compile-Time**: Define `PRECOMPILED_LOG_LEVEL` before including hectic.h
|
||||
```c
|
||||
#define PRECOMPILED_LOG_LEVEL LOG_LEVEL_INFO
|
||||
#include <hectic.h>
|
||||
```
|
||||
|
||||
## Logging Best Practices
|
||||
|
||||
### DO
|
||||
|
||||
- **Be specific and concise**: Include relevant details but avoid verbose descriptions
|
||||
- **Include context**: Add identifiers (IDs, filenames, pointers) to help with troubleshooting
|
||||
- **Use the appropriate level**: Understand the purpose of each level and use it accordingly
|
||||
- **Log state transitions**: Important changes in application state should be logged
|
||||
- **Use structured data**: When possible, include structured information rather than unformatted text
|
||||
|
||||
### DON'T
|
||||
|
||||
- **Log sensitive information**: Never log passwords, tokens, or personal information
|
||||
- **Overuse high-severity levels**: Reserve WARN and EXCEPTION for real issues
|
||||
- **Log in tight loops**: Avoid excessive logging in performance-critical paths
|
||||
- **Use inconsistent formats**: Follow a consistent message format throughout your code
|
||||
- **Ignore log levels**: Don't use DEBUG for important operational events or EXCEPTION for minor issues
|
||||
|
||||
## Examples of Good Logging
|
||||
|
||||
### Error Handling Pattern
|
||||
|
||||
```c
|
||||
void *allocate_resource(size_t size) {
|
||||
raise_debug("Allocating %zu bytes", size);
|
||||
|
||||
void *ptr = malloc(size);
|
||||
if (!ptr) {
|
||||
raise_exception("Memory allocation failed for %zu bytes", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raise_debug("Successfully allocated %zu bytes at %p", size, ptr);
|
||||
return ptr;
|
||||
}
|
||||
```
|
||||
|
||||
### State Transition Pattern
|
||||
|
||||
```c
|
||||
void change_connection_state(Connection *conn, ConnState new_state) {
|
||||
raise_debug("Connection %p state change requested: %s -> %s",
|
||||
conn, conn_state_to_string(conn->state), conn_state_to_string(new_state));
|
||||
|
||||
if (!is_valid_transition(conn->state, new_state)) {
|
||||
raise_warn("Invalid state transition from %s to %s",
|
||||
conn_state_to_string(conn->state), conn_state_to_string(new_state));
|
||||
return;
|
||||
}
|
||||
|
||||
ConnState old_state = conn->state;
|
||||
conn->state = new_state;
|
||||
|
||||
raise_info("Connection %s state changed: %s -> %s",
|
||||
conn->id, conn_state_to_string(old_state), conn_state_to_string(new_state));
|
||||
}
|
||||
```
|
||||
|
||||
### Operation Pattern
|
||||
|
||||
```c
|
||||
int process_file(const char *filename) {
|
||||
raise_log("Processing file: %s", filename);
|
||||
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
raise_warn("Could not open file %s: %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Process file...
|
||||
|
||||
raise_info("Successfully processed file %s: %d records", filename, record_count);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user