Skip to content

Commit 37d6165

Browse files
committed
update
1 parent 48759a9 commit 37d6165

6 files changed

Lines changed: 189 additions & 12 deletions

File tree

README.md

Lines changed: 189 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,204 @@
99

1010
---
1111

12-
## Summary
12+
`df_log` is a massive upgrade from `print()`. It makes your console output beautiful, readable, and powerful, turning your logs into a central event bus for debugging, analytics, and crash reporting. It’s for the developer who wants the simplicity of `print()` but with more clarity, context, and control.
1313

14-
A starting point for Dart or Flutter packages.
14+
## ✨ Features
1515

16-
## Installation
16+
- **Categorized Logging:** Pre-defined methods like `Log.info`, `Log.err`, `Log.ok` for semantic logging.
17+
- **Beautifully Styled Output:** Uses ANSI colors and emojis for clear, readable logs in supported consoles.
18+
- **Tag-Based Filtering:** Assign tags to logs and filter the console output to show only what you need.
19+
- **In-Memory Log Storage:** Keeps a configurable queue of recent logs for debugging or inspection.
20+
- **Release Mode Control:** Configure logs and assertions to be active even in release builds.
21+
- **Customizable Output:** Show or hide timestamps, log IDs, and tags.
22+
- **IDE Integration:** Optionally uses `dart:developer`'s `log` function for a richer experience in some IDEs.
23+
- **Isolate-Friendly:** Set `Log.context` per isolate to instantly see where logs come from. Works on web too.
24+
- **Log Export:** Export stored logs as JSONL with `Log.exportLogsAsJsonLines()`.
25+
- **Extensible:** Add custom callbacks to integrate with other services (e.g., crash reporting).
1726

18-
```sh
19-
dart pub add df_log
20-
# or, for a Flutter project:
21-
flutter pub add df_log
22-
```
27+
## 🚀 Getting Started
28+
29+
For an introduction, please refer to this article:
30+
31+
- **MEDIUM.COM** [Dart Logging: Your New Best Friend](https://medium.com/@dev-cetera/dart-logging-your-new-best-friend-7e0dbd701dc7)
32+
- **DEV.TO** [Dart Logging: Your New Best Friend](https://dev.to/dev_cetera/dart-logging-your-new-best-friebd-ae1)
33+
- **GITHUB** [Dart Logging: Your New Best Friend](https://github.com/dev-cetera/df_log/blob/main/ARTICLE.md)
34+
35+
## 🧐 Overview
2336

24-
## Usage
37+
### 💡 1. Categorized Logs
38+
39+
The package comes with a few default log types that you can use creatively.
2540

2641
```dart
2742
import 'package:df_log/df_log.dart';
2843
2944
void main() {
30-
// ...
45+
Log.start('Application starting...');
46+
Log.info('Checking for user session...');
47+
Log.alert('Network connection is slow. Retrying in 5s.');
48+
Log.ok('User session found and validated.');
49+
Log.err('Failed to load user preferences!');
50+
Log.stop('Application shutting down.');
51+
}
52+
```
53+
54+
### 💡 2. Colored Logs
55+
56+
Colored logs enhance readability and help you quickly identify different types of messages in the console. By applying distinct colors, you can easily track errors, successes, warnings, and other log types at a glance.
57+
58+
```dart
59+
Log.printRed('This is printed in RED!');
60+
Log.printGreen('This is printed in GREEN!');
61+
Log.printBlue('This is printed in BLUE!');
62+
Log.printYellow('This is printed in YELLOW!');
63+
Log.printCyan('This is printed in CYAN!');
64+
Log.printPurple('This is printed in PURPLE!');
65+
Log.printBlack('This is printed in BLACK!');
66+
Log.printWhite('This is printed in WHITE!');
67+
// and many more...
68+
```
69+
70+
### 💡 3. Tags
71+
72+
Using tags with logs simplifies debugging and organization. Tags allow you to filter logs by including or excluding specific categories, making it easier to focus on relevant information. They can also help categorize data for analytics or other purposes.
73+
74+
```dart
75+
// main.dart
76+
void main() {
77+
// Only show logs tagged with #auth or #ui.
78+
Log.addTags({#auth, #ui});
79+
80+
// Printed!
81+
Log.info('Initializing UI elements...', tags: {#ui});
82+
Log.ok('User logged in.', tags: {#auth});
83+
Log.trace('Connecting to database...', tags: {#auth, #firebase});
84+
85+
// Not printed - #db tag doesn't exist!
86+
Log.trace('Connecting to database...', tags: {#db});
87+
88+
// Not printed - #ui exists but #button doesn't!
89+
Log.trace('Rendering button...', tags: {#ui, #button});
90+
91+
// Printed!
92+
Log.addTags({#button});
93+
Log.trace('Rendering button...', tags: {#ui, #button});
94+
}
95+
```
96+
97+
### 💡 4. Structured Metadata
98+
99+
Pair a log with a structured `metadata` payload that travels through `Log.addCallback` to analytics or crash reporting. The console output stays human-readable; the metadata is for machines.
100+
101+
```dart
102+
void main() {
103+
// Forward user-action logs to analytics, with their metadata as event params.
104+
Log.addCallback((logItem) {
105+
if (logItem.tags.contains(#userAction)) {
106+
final metadata = logItem.metadata as Map<String, Object?>?;
107+
// analytics.logEvent(name: logItem.message.toString(), parameters: metadata);
108+
}
109+
});
110+
111+
// Call sites pass a stable event name as the message and the params as metadata.
112+
Log.info(
113+
'create_group',
114+
tags: {#userAction},
115+
metadata: {'has_description': true, 'member_count': 1},
116+
);
117+
118+
Log.err(
119+
'item_sync_failed',
120+
tags: {#userAction},
121+
metadata: {'item_id': 'abc123', 'status_code': 500},
122+
);
123+
}
124+
```
125+
126+
`metadata` is `Object?`, so any serializable shape works (maps, lists, nested structures). It also lands in `LogItem.toJson()`, so `Log.exportLogsAsJsonLines()` carries it through.
127+
128+
### 💡 5. Isolate Context
129+
130+
When debugging across isolates, set `Log.context` at the start of each isolate. Since Dart statics are per-isolate, each isolate gets its own value automatically - no locking, no shared state, no complexity.
131+
132+
```dart
133+
void main() {
134+
Log.context = 'MAIN';
135+
Log.info('Starting app');
136+
// Output: [🟣 example #5 MAIN] Starting app
137+
runApp(const App());
138+
}
139+
140+
@pragma("vm:entry-point")
141+
void overlayMain() {
142+
Log.context = 'OVERLAY';
143+
Log.info('Overlay started');
144+
// Output: [🟣 example #5 OVERLAY] Overlay started
145+
runApp(const Overlay());
146+
}
147+
```
148+
149+
Use a short tag like `M` to save space, or a full string like `ISOLATE_MAIN` for clarity.
150+
151+
**How it works:** In Dart, each isolate has its own memory. All `Log` statics (`context`, `items`, `activeTags`, etc.) are independent per isolate. This means `Log.context = 'OVERLAY'` in one isolate has zero effect on another. The only shared thing is the console output (stdout), which is why `Log.context` exists - so you can tell which isolate printed what. This works on all platforms including web.
152+
153+
### 💡 6. Configuration
154+
155+
You can customize the logging behavior to suit your needs, including styling, output format, and storage options. The Log class provides various settings to control how logs are displayed and managed.
156+
157+
```dart
158+
void main() {
159+
// Set a label for the current isolate (useful for multi-isolate debugging).
160+
Log.context = 'MAIN';
161+
162+
// Enable or disable ANSI colors and icons. Disable this if your console doesn't support it.
163+
Log.enableStyling = true;
164+
165+
// Show a timestamp like 'HH:mm:ss.SSS' in the printed output.
166+
Log.showTimestamps = true;
167+
168+
// Show tags like '#auth #network' in the printed output.
169+
Log.showTags = true;
170+
171+
// Show a unique ID for each log item in the printed output.
172+
Log.showIds = false;
173+
174+
// By default, logs only appear in debug mode.
175+
Log.enableReleaseAsserts = true;
176+
177+
// Keep a history of logs in memory.
178+
Log.storeLogs = true;
179+
180+
// Set the max number of logs to store.
181+
Log.maxStoredLogs = 500;
182+
183+
// Use a richer log viewer in supported IDEs (like VS Code's Debug Console).
184+
Log.useDeveloperLog();
185+
186+
// Or revert to the standard `print` function.
187+
Log.useStandardPrint();
188+
189+
// Add a function to trigger each time a log is added.
190+
final callback = Log.addCallback((LogItem logItem) {
191+
final json = logItem.toJson();
192+
// TODO: Send your log to something like Google Analytics.
193+
});
194+
195+
// Remove an existing callback.
196+
Log.removeCallback(callback);
197+
198+
// Get notified when old logs are discarded from the queue.
199+
Log.onLogDiscarded = (discardedItem) {
200+
// TODO: Forward to analytics before it's gone.
201+
};
202+
203+
// Clear log history.
204+
Log.clear();
205+
206+
// Export all stored logs as a JSONL string.
207+
final jsonl = Log.exportLogsAsJsonLines();
208+
209+
runApp(MyApp());
31210
}
32211
```
33212

@@ -57,8 +236,6 @@ No matter how you choose to contribute, your involvement is greatly appreciated
57236

58237
If you're enjoying this package and find it valuable, consider showing your appreciation with a small donation. Every bit helps in supporting future development. You can donate here: https://www.buymeacoffee.com/dev_cetera
59238

60-
<a href="https://www.buymeacoffee.com/dev_cetera" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" height="40"></a>
61-
62239
## LICENSE
63240

64241
This project is released under the [MIT License](https://raw.githubusercontent.com/dev-cetera/df_log/main/LICENSE). See [LICENSE](https://raw.githubusercontent.com/dev-cetera/df_log/main/LICENSE) for more information.

doc/assets/example.png

-277 KB
Binary file not shown.

doc/assets/screenshot1.png

-23.5 KB
Binary file not shown.

doc/assets/screenshot2.png

-189 KB
Binary file not shown.

doc/assets/screenshot3.png

-43.8 KB
Binary file not shown.

doc/assets/screenshot4.png

-68.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)