Skip to content

Commit 9c5824e

Browse files
committed
Add logging documentation
New documentation covering the three Bold logging systems: - Simple file logging (BoldThreadSafeLog) - Modern multi-sink logging (BoldLogManager) - Legacy UI logging with progress tracking (BoldLogHandler) Includes practical examples for each system.
1 parent cca7c39 commit 9c5824e

2 files changed

Lines changed: 335 additions & 0 deletions

File tree

docs/concepts/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ flowchart TB
1616
ObjectSpace[Object Space]
1717
OCL[OCL Queries]
1818
Subscriptions[Subscription System]
19+
Logging[Logging System]
1920
end
2021
2122
subgraph Data["Data Layer"]
@@ -40,6 +41,7 @@ flowchart TB
4041
| **OCL** | Query language for navigating and filtering objects | [OCL Queries](ocl.md) |
4142
| **Persistence** | Automatic object-relational mapping | [Persistence](persistence.md) |
4243
| **Subscriptions** | Observer pattern for reactive updates | [Subscriptions](subscriptions.md) |
44+
| **Logging** | Flexible logging with multiple output options | [Logging](logging.md) |
4345

4446
## The Bold Workflow
4547

docs/concepts/logging.md

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
# Logging
2+
3+
Bold for Delphi provides flexible logging capabilities through three complementary systems, each suited for different use cases.
4+
5+
## Quick Start
6+
7+
The simplest way to add logging to your Bold application:
8+
9+
```pascal
10+
uses
11+
BoldThreadSafeLog;
12+
13+
// Initialize at application startup
14+
BoldInitLog('app.log', 'error.log', '', 10*1024*1024);
15+
16+
// Log messages anywhere in your code
17+
BoldLog('Application started');
18+
BoldLog('Processing %d records', [RecordCount]);
19+
BoldLogError('Database connection failed: %s', [ErrorMsg]);
20+
21+
// Clean up at shutdown
22+
BoldDoneLog;
23+
```
24+
25+
## Logging Systems Overview
26+
27+
| System | Best For | Output | Thread-Safe |
28+
|--------|----------|--------|-------------|
29+
| **Simple** (BoldThreadSafeLog) | File-based logging | Log files | Yes |
30+
| **Modern** (BoldLogManager) | Production apps with multiple outputs | Files, Console, Debugger, Memory | Yes |
31+
| **Legacy** (BoldLogHandler) | UI apps with progress tracking | UI forms | Yes |
32+
33+
## Simple File Logging
34+
35+
The `BoldThreadSafeLog` unit provides straightforward file-based logging with automatic timestamps.
36+
37+
### Setup
38+
39+
```pascal
40+
uses
41+
BoldThreadSafeLog;
42+
43+
procedure InitializeLogging;
44+
begin
45+
// Parameters: MainLog, ErrorLog, ThreadLog, MaxFileSize
46+
BoldInitLog(
47+
'logs\app.log', // Main log file
48+
'logs\error.log', // Error-specific log
49+
'logs\thread.log', // Thread activity log (optional, use '' to skip)
50+
10 * 1024 * 1024 // Max 10 MB per file
51+
);
52+
end;
53+
54+
procedure FinalizeLogging;
55+
begin
56+
BoldDoneLog;
57+
end;
58+
```
59+
60+
### Usage
61+
62+
```pascal
63+
// Simple message
64+
BoldLog('User logged in');
65+
66+
// Formatted message
67+
BoldLog('Processed %d of %d items', [Current, Total]);
68+
69+
// Error logging (always includes thread ID)
70+
BoldLogError('Failed to save: %s', [E.Message]);
71+
72+
// Thread activity logging
73+
BoldLogThread('Worker thread started');
74+
```
75+
76+
### Log File Format
77+
78+
```
79+
2025-01-15T10:30:45.123 Application started
80+
2025-01-15T10:30:45.456 Processing 100 records
81+
2025-01-15T10:30:46.789 Failed to connect (ThreadID=1234)
82+
```
83+
84+
## Modern Multi-Sink Logging
85+
86+
The `BoldLogInterfaces` and `BoldLogSinks` units provide a flexible sink-based architecture for production applications.
87+
88+
### Log Levels
89+
90+
```pascal
91+
type
92+
TBoldLogLevel = (
93+
llTrace, // Detailed tracing
94+
llDebug, // Debug information
95+
llInfo, // General information
96+
llWarning, // Warning conditions
97+
llError // Error conditions
98+
);
99+
```
100+
101+
### Available Sinks
102+
103+
| Sink | Description |
104+
|------|-------------|
105+
| `TBoldFileLogSink` | Log to files with automatic size management |
106+
| `TBoldConsoleLogSink` | Output to console (WriteLn) |
107+
| `TBoldDebugLogSink` | OutputDebugString - visible in IDE debugger |
108+
| `TBoldMemoryLogSink` | In-memory buffer for UI display |
109+
110+
### Basic Setup
111+
112+
```pascal
113+
uses
114+
BoldLogInterfaces,
115+
BoldLogSinks;
116+
117+
procedure SetupLogging;
118+
var
119+
FileSink: TBoldFileLogSink;
120+
begin
121+
// Create a file sink with 5 MB max size
122+
FileSink := TBoldFileLogSink.Create('app.log', 5 * 1024 * 1024);
123+
BoldLogManager.RegisterSink(FileSink);
124+
end;
125+
```
126+
127+
### Multiple Sinks
128+
129+
```pascal
130+
procedure SetupProductionLogging;
131+
var
132+
FileSink: TBoldFileLogSink;
133+
ConsoleSink: TBoldConsoleLogSink;
134+
DebugSink: TBoldDebugLogSink;
135+
begin
136+
// File: All levels
137+
FileSink := TBoldFileLogSink.Create('app.log');
138+
FileSink.Levels := [llInfo, llWarning, llError];
139+
BoldLogManager.RegisterSink(FileSink);
140+
141+
// Console: Errors only
142+
ConsoleSink := TBoldConsoleLogSink.Create;
143+
ConsoleSink.Levels := [llError];
144+
BoldLogManager.RegisterSink(ConsoleSink);
145+
146+
// Debug output: Everything during development
147+
DebugSink := TBoldDebugLogSink.Create;
148+
DebugSink.Levels := [llTrace, llDebug, llInfo, llWarning, llError];
149+
BoldLogManager.RegisterSink(DebugSink);
150+
end;
151+
```
152+
153+
### Logging Messages
154+
155+
```pascal
156+
uses
157+
BoldLogInterfaces;
158+
159+
procedure DoSomething;
160+
begin
161+
BoldLog('Starting operation', llInfo);
162+
try
163+
// ... do work ...
164+
BoldLog('Processed %d items', [Count], llDebug);
165+
except
166+
on E: Exception do
167+
BoldLog('Operation failed: %s', [E.Message], llError);
168+
end;
169+
end;
170+
```
171+
172+
### In-Memory Sink for UI
173+
174+
```pascal
175+
var
176+
MemorySink: TBoldMemoryLogSink;
177+
178+
procedure SetupLogViewer;
179+
begin
180+
// Keep last 1000 lines in memory
181+
MemorySink := TBoldMemoryLogSink.Create(1000);
182+
BoldLogManager.RegisterSink(MemorySink);
183+
end;
184+
185+
procedure RefreshLogView;
186+
begin
187+
// Display in a TMemo or similar
188+
Memo1.Lines.Assign(MemorySink.Lines);
189+
end;
190+
```
191+
192+
## Legacy UI Logging
193+
194+
The `BoldLogHandler` unit provides logging with progress tracking, ideal for long-running operations with UI feedback.
195+
196+
### Basic Usage
197+
198+
```pascal
199+
uses
200+
BoldLogHandler;
201+
202+
procedure ImportData;
203+
begin
204+
BoldLog.StartLog('Data Import');
205+
try
206+
BoldLog.Log('Loading file...');
207+
// ... load file ...
208+
209+
BoldLog.Log('Processing records...');
210+
// ... process ...
211+
212+
BoldLog.Log('Import complete');
213+
finally
214+
BoldLog.EndLog;
215+
end;
216+
end;
217+
```
218+
219+
### Progress Tracking
220+
221+
```pascal
222+
procedure ProcessRecords(Records: TList);
223+
var
224+
I: Integer;
225+
begin
226+
BoldLog.ProgressMax := Records.Count;
227+
BoldLog.LogIndent('Processing records');
228+
try
229+
for I := 0 to Records.Count - 1 do
230+
begin
231+
BoldLog.LogFmt('Record %d of %d', [I + 1, Records.Count]);
232+
ProcessRecord(Records[I]);
233+
BoldLog.ProgressStep; // Increment progress
234+
end;
235+
finally
236+
BoldLog.Dedent;
237+
end;
238+
end;
239+
```
240+
241+
### Nested Operations with Indentation
242+
243+
```pascal
244+
procedure ComplexOperation;
245+
begin
246+
BoldLog.LogIndent('Starting complex operation');
247+
try
248+
BoldLog.Log('Phase 1: Validation');
249+
ValidateData;
250+
251+
BoldLog.LogIndent('Phase 2: Processing');
252+
try
253+
ProcessItems;
254+
finally
255+
BoldLog.Dedent;
256+
end;
257+
258+
BoldLog.Log('Phase 3: Cleanup');
259+
Cleanup;
260+
finally
261+
BoldLog.LogDedent; // Log message and dedent
262+
end;
263+
end;
264+
```
265+
266+
Output:
267+
```
268+
Starting complex operation
269+
Phase 1: Validation
270+
Phase 2: Processing
271+
Item 1 processed
272+
Item 2 processed
273+
Phase 3: Cleanup
274+
Operation complete
275+
```
276+
277+
### Log Types
278+
279+
```pascal
280+
BoldLog.Log('Information message', ltInfo);
281+
BoldLog.Log('Detailed debug info', ltDetail);
282+
BoldLog.Log('Warning: low memory', ltWarning);
283+
BoldLog.Log('Error: file not found', ltError);
284+
BoldLog.Log('', ltSeparator); // Visual separator line
285+
```
286+
287+
## Choosing the Right System
288+
289+
**Use Simple (BoldThreadSafeLog) when:**
290+
- You need basic file logging
291+
- Minimal setup is preferred
292+
- You want separate error and thread logs
293+
294+
**Use Modern (BoldLogManager) when:**
295+
- You need multiple output destinations
296+
- Level-based filtering is required
297+
- You want to display logs in the UI
298+
- Building a production application
299+
300+
**Use Legacy (BoldLogHandler) when:**
301+
- You need progress tracking
302+
- UI feedback during long operations is important
303+
- You want hierarchical/nested log display
304+
305+
## Thread Safety
306+
307+
All three logging systems are thread-safe:
308+
309+
- **Simple**: Uses `TCriticalSection` for file access
310+
- **Modern**: Uses `TMonitor` for sink management
311+
- **Legacy**: Uses subscription pattern with thread synchronization
312+
313+
```pascal
314+
// Safe to call from any thread
315+
TThread.CreateAnonymousThread(
316+
procedure
317+
begin
318+
BoldLog('Background task started');
319+
// ... do work ...
320+
BoldLog('Background task completed');
321+
end
322+
).Start;
323+
```
324+
325+
## Source Files
326+
327+
| File | Description |
328+
|------|-------------|
329+
| `Source/Common/Logging/BoldThreadSafeLog.pas` | Simple file logging |
330+
| `Source/Common/Logging/BoldLogInterfaces.pas` | Modern sink interfaces |
331+
| `Source/Common/Logging/BoldLogSinks.pas` | Sink implementations |
332+
| `Source/Common/Logging/BoldLogHandler.pas` | Legacy UI logging |
333+
| `Source/Common/Logging/BoldLogReceiverInterface.pas` | Receiver interfaces |

0 commit comments

Comments
 (0)