```/*
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
* Description: Log manager usage examples and test cases.
*
* This file demonstrates how to use the log_manager API for timestamp-based
* log file storage with automatic rotation on a littlefs filesystem.
*/
#include "log_manager.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// ==================== Example 1: Basic Usage ====================
/**
* @brief Demonstrate basic log write and read operations
*/
void example_basic_usage(void)
{
printf("\n=== Example 1: Basic Log Write and Read ===\n");
// Initialize log manager
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Write some log messages
log_manager_write("System started successfully");
log_manager_write("Device initialization completed");
log_manager_write("All sensors are online");
// Get current file info
log_file_info_t current_file;
if (log_manager_get_current_file_info(¤t_file) == 0) {
printf("Current log file: %s\n", current_file.filename);
printf("Current file size: %u bytes\n", current_file.size);
}
// Cleanup
log_manager_cleanup();
}
// ==================== Example 2: Write with Log Levels ====================
/**
* @brief Demonstrate logging with different log levels
*/
void example_log_levels(void)
{
printf("\n=== Example 2: Log Levels (INFO, WARN, ERROR, DEBUG) ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Write logs with different levels
log_manager_write_level("INFO", "Application started");
log_manager_write_level("DEBUG", "Initializing configuration");
log_manager_write_level("INFO", "Configuration loaded successfully");
log_manager_write_level("WARN", "Memory usage above 80%");
log_manager_write_level("ERROR", "Failed to connect to network");
log_manager_write_level("INFO", "Retrying connection in 5 seconds");
log_manager_cleanup();
}
// ==================== Example 3: Formatted Logging ====================
/**
* @brief Demonstrate printf-style formatted logging
*/
void example_formatted_logging(void)
{
printf("\n=== Example 3: Formatted Logging (printf-style) ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Use printf-style formatting
int temperature = 28;
int humidity = 65;
float voltage = 3.27f;
log_manager_printf("Temperature: %d°C, Humidity: %d%%", temperature, humidity);
log_manager_printf("Supply voltage: %.2fV", voltage);
log_manager_printf("Device ID: %s, FW Version: %s", "WS63-001", "v1.2.3");
// Simulate sensor readings over time
for (int i = 0; i < 5; i++) {
log_manager_printf("Sensor reading #%d: ADC value = 0x%04X, Status = OK",
i + 1, 0xABCD + i);
usleep(100000); // 100ms delay
}
log_manager_cleanup();
}
// ==================== Example 4: File Rotation ====================
/**
* @brief Demonstrate automatic log file rotation when size exceeds 1MB
* Note: For testing, we can simulate with smaller file sizes
*/
void example_file_rotation(void)
{
printf("\n=== Example 4: Automatic File Rotation ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
printf("Writing logs to test automatic rotation...\n");
// Write large amount of data to trigger rotation
for (int i = 0; i < 100; i++) {
char log_msg[256];
snprintf(log_msg, sizeof(log_msg),
"Log entry %d: This is a test message with some data. "
"Timestamp: %ld. Counter: %d. Status: Active.",
i + 1, time(NULL), i);
if (log_manager_write(log_msg) < 0) {
printf("Failed to write log entry %d\n", i + 1);
}
if (i % 20 == 0) {
log_file_info_t current_file;
if (log_manager_get_current_file_info(¤t_file) == 0) {
printf("Entry %d: File size = %u bytes\n", i + 1, current_file.size);
}
}
usleep(1000); // 1ms delay
}
// Show all log files
log_file_info_t file_list[20];
int count = 0;
if (log_manager_list_files(file_list, 20, &count) == 0) {
printf("\nTotal log files created: %d\n", count);
for (int i = 0; i < count; i++) {
printf(" File: %s - Size: %u bytes\n",
file_list[i].filename, file_list[i].size);
}
}
log_manager_cleanup();
}
// ==================== Example 5: Read Log Files ====================
/**
* @brief Demonstrate reading log files by name
*/
void example_read_logs(void)
{
printf("\n=== Example 5: Read Log Files ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Write some test logs
printf("Writing test logs...\n");
log_manager_write("Test log line 1");
log_manager_write("Test log line 2");
log_manager_write("Test log line 3");
// Get current file info
log_file_info_t current_file;
if (log_manager_get_current_file_info(¤t_file) == 0) {
printf("Current log file: %s\n", current_file.filename);
// Read the log file
char buffer[4096];
int bytes_read = log_manager_read(
strrchr(current_file.filename, '/') + 1, // Get filename without path
buffer,
sizeof(buffer)
);
if (bytes_read > 0) {
printf("\nLog file content (%d bytes):\n", bytes_read);
printf("=====================================\n");
printf("%s\n", buffer);
printf("=====================================\n");
}
}
log_manager_cleanup();
}
// ==================== Example 6: Read Partial Log Files ====================
/**
* @brief Demonstrate reading specific portions of log files
*/
void example_read_partial_logs(void)
{
printf("\n=== Example 6: Read Partial Log (with offset) ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Write test data
for (int i = 0; i < 20; i++) {
log_manager_printf("Log line %d: Some test data content", i + 1);
}
log_file_info_t current_file;
if (log_manager_get_current_file_info(¤t_file) == 0) {
const char *filename = strrchr(current_file.filename, '/') + 1;
unsigned int file_size = current_file.size;
printf("Total file size: %u bytes\n", file_size);
// Read last 512 bytes
if (file_size > 512) {
char buffer[512];
int bytes_read = log_manager_read_offset(
filename,
buffer,
sizeof(buffer),
file_size - 512
);
if (bytes_read > 0) {
printf("\nLast 512 bytes of log:\n");
printf("(showing from offset %u)\n", file_size - 512);
printf("=====================================\n");
printf("%s\n", buffer);
printf("=====================================\n");
}
}
}
log_manager_cleanup();
}
// ==================== Example 7: File Management ====================
/**
* @brief Demonstrate file listing, deletion, and cleanup
*/
void example_file_management(void)
{
printf("\n=== Example 7: File Management ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Create multiple log files
printf("Creating test log files...\n");
for (int batch = 0; batch < 3; batch++) {
for (int i = 0; i < 10; i++) {
log_manager_printf("Batch %d - Entry %d: Test data", batch + 1, i + 1);
}
usleep(100000); // Small delay
}
// List all files
log_file_info_t file_list[20];
int count = 0;
if (log_manager_list_files(file_list, 20, &count) == 0) {
printf("\nCurrent log files (%d total):\n", count);
unsigned int total_size = 0;
for (int i = 0; i < count; i++) {
printf(" [%d] %s - %u bytes\n", i + 1,
file_list[i].filename, file_list[i].size);
total_size += file_list[i].size;
}
printf("Total size: %u bytes\n", total_size);
}
// Get total size using API
unsigned int total_size = 0;
if (log_manager_get_total_size(&total_size) == 0) {
printf("\nTotal log storage used: %u bytes\n", total_size);
}
// Example: Keep only latest 2 files
printf("\nCleaning up old files (keeping only latest 2)...\n");
int deleted = log_manager_cleanup_old_files(2);
printf("Deleted %d old files\n", deleted);
// List remaining files
memset(file_list, 0, sizeof(file_list));
count = 0;
if (log_manager_list_files(file_list, 20, &count) == 0) {
printf("Remaining files (%d total):\n", count);
for (int i = 0; i < count; i++) {
printf(" %s - %u bytes\n",
file_list[i].filename, file_list[i].size);
}
}
log_manager_cleanup();
}
// ==================== Example 8: Real-world Scenario ====================
/**
* @brief Simulates a real-world IoT device logging scenario
*/
void example_realworld_scenario(void)
{
printf("\n=== Example 8: Real-world IoT Device Scenario ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
printf("Simulating IoT device operation...\n\n");
// Simulate device startup sequence
log_manager_write_level("INFO", "=== System Startup ===");
log_manager_write_level("INFO", "Firmware version: v2.1.0");
log_manager_write_level("DEBUG", "Initializing peripherals");
// Simulate sensor readings
printf("Logging sensor data for 30 seconds...\n");
int start_time = time(NULL);
int reading_count = 0;
while (time(NULL) - start_time < 30 && reading_count < 50) {
int temp = 25 + (rand() % 10);
int humidity = 40 + (rand() % 30);
int rssi = -45 - (rand() % 40); // WiFi signal strength
log_manager_printf(
"SENSOR_READ: Temp=%dC Humidity=%d%% RSSI=%ddBm Battery=4.2V",
temp, humidity, rssi
);
// Occasional warnings and errors
if ((reading_count % 7) == 0) {
log_manager_write_level("WARN", "High temperature warning");
}
if ((reading_count % 13) == 0) {
log_manager_write_level("ERROR", "Sensor read timeout, retrying...");
}
if ((reading_count % 13) == 1) {
log_manager_write_level("INFO", "Sensor recovered, operation normal");
}
reading_count++;
usleep(600000); // 600ms per reading
}
printf("Logged %d sensor readings\n\n", reading_count);
// System shutdown
log_manager_write_level("INFO", "=== System Shutdown ===");
log_manager_write_level("INFO", "Closing all connections");
log_manager_write_level("INFO", "Saving configuration");
log_manager_write_level("INFO", "System halted");
// Show statistics
log_file_info_t file_list[20];
int count = 0;
if (log_manager_list_files(file_list, 20, &count) == 0) {
printf("\nLogging Statistics:\n");
printf(" Total log files: %d\n", count);
unsigned int total_size = 0;
for (int i = 0; i < count; i++) {
total_size += file_list[i].size;
}
printf(" Total log size: %u bytes\n", total_size);
printf(" Average file size: %u bytes\n",
count > 0 ? total_size / count : 0);
}
log_manager_cleanup();
}
// ==================== Example 9: Flash Storage Information ====================
/**
* @brief Demonstrate retrieving Flash storage information
*/
void example_flash_storage_info(void)
{
printf("\n=== Example 9: Flash Storage Information ===\n");
if (log_manager_init() != 0) {
printf("Failed to initialize log manager\n");
return;
}
// Write some log data first
printf("Writing some log data...\n");
for (int i = 0; i < 20; i++) {
log_manager_printf("Test log entry %d: Temperature=28.5°C, Humidity=65%%", i);
}
// Get Flash storage information
unsigned int start_addr = 0;
unsigned int total_size = 0;
unsigned int free_size = 0;
if (log_manager_get_flash_info(&start_addr, &total_size, &free_size) == 0) {
printf("\n=== Flash Storage Information ===\n");
printf("Start Address: 0x%08X\n", start_addr);
printf("Total Size: %u bytes (%.2f KB, %.2f MB)\n",
total_size, total_size / 1024.0, total_size / (1024.0 * 1024.0));
printf("Free Space: %u bytes (%.2f KB, %.2f MB)\n",
free_size, free_size / 1024.0, free_size / (1024.0 * 1024.0));
unsigned int used_size = total_size - free_size;
printf("Used Space: %u bytes (%.2f KB, %.2f MB)\n",
used_size, used_size / 1024.0, used_size / (1024.0 * 1024.0));
// Calculate percentage
float usage_percent = (total_size > 0) ? (100.0 * used_size / total_size) : 0;
printf("Storage Usage: %.1f%%\n", usage_percent);
// Show warning if storage is full
if (usage_percent > 90.0f) {
printf("⚠️ WARNING: Storage is more than 90%% full!\n");
} else if (usage_percent > 70.0f) {
printf("⚠️ NOTICE: Storage usage is above 70%%\n");
}
// Show remaining space
if (free_size > 0) {
unsigned int estimated_files = free_size / (100 * 1024); // Assume ~100KB per file
printf("Estimated space for ~%u more log files (100KB each)\n",
estimated_files > 0 ? estimated_files : 1);
}
} else {
printf("Failed to get Flash storage information\n");
}
// Get log file statistics
log_file_info_t file_list[20];
int count = 0;
if (log_manager_list_files(file_list, 20, &count) == 0) {
printf("\n=== Log File Statistics ===\n");
printf("Number of log files: %d\n", count);
unsigned int total_log_size = 0;
for (int i = 0; i < count; i++) {
total_log_size += file_list[i].size;
printf(" [%d] %s - %u bytes (%.2f KB)\n", i+1,
file_list[i].filename, file_list[i].size,
file_list[i].size / 1024.0);
}
printf("Total log size: %u bytes (%.2f KB, %.2f MB)\n",
total_log_size, total_log_size / 1024.0,
total_log_size / (1024.0 * 1024.0));
}
log_manager_cleanup();
}
// ==================== Main Test Runner ====================
int main(void)
{
printf("========================================\n");
printf("Log Manager API Usage Examples\n");
printf("Based on littlefs for MCU applications\n");
printf("========================================\n");
// Run all examples
example_basic_usage();
example_log_levels();
example_formatted_logging();
example_file_rotation();
example_read_logs();
example_read_partial_logs();
example_file_management();
example_realworld_scenario();
example_flash_storage_info();
printf("\n========================================\n");
printf("All examples completed successfully!\n");
printf("========================================\n");
return 0;
}