Foreword |
|
xiii | |
Preface |
|
xvi | |
Acknowledgments |
|
xviii | |
About this Book |
|
xx | |
About the Author |
|
xxv | |
About the cover illustration |
|
xxvi | |
|
Part 1 From zero to "Hello World" |
|
|
|
1 Introduction to Fluentd |
|
|
3 | (27) |
|
1.1 Elevator pitch for Fluentd |
|
|
4 | (2) |
|
|
4 | (1) |
|
Fluentd compared to middleware |
|
|
5 | (1) |
|
1.2 Why do we produce logs? |
|
|
6 | (3) |
|
|
9 | (3) |
|
|
9 | (1) |
|
Three pillars of observability |
|
|
10 | (2) |
|
|
12 | (2) |
|
Unifying logs vs. log analytics |
|
|
14 | (1) |
|
|
14 | (4) |
|
|
15 | (1) |
|
Comparing Fluentd and Logstash |
|
|
16 | (1) |
|
The relationship between Fluentd and Fluent Bit |
|
|
17 | (1) |
|
The relationship between Logstash and Beats |
|
|
18 | (1) |
|
1.6 Log routing as a vehicle for security |
|
|
18 | (1) |
|
|
19 | (1) |
|
|
20 | (3) |
|
|
20 | (2) |
|
|
22 | (1) |
|
Relationship to major cloud vendors PaaS/IaaS |
|
|
22 | (1) |
|
1.9 Where can Fluentd and Fluent Bit be used? |
|
|
23 | (1) |
|
|
23 | (1) |
|
1.10 Fluentd UI-based editing |
|
|
24 | (2) |
|
|
26 | (1) |
|
1.12 How Fluentd can be used to make operational tasks easier |
|
|
27 | (3) |
|
|
27 | (1) |
|
Making logs more meaningful |
|
|
27 | (1) |
|
|
28 | (1) |
|
|
28 | (1) |
|
Controlling log data costs |
|
|
28 | (1) |
|
|
28 | (1) |
|
Rapid operational consolidation |
|
|
29 | (1) |
|
2 Concepts, architecture, and deployment of Fluentd |
|
|
30 | (35) |
|
2.1 Architecture and core concepts |
|
|
30 | (8) |
|
The makeup of a log event |
|
|
31 | (1) |
|
|
32 | (1) |
|
|
33 | (2) |
|
Fluent configuration execution order |
|
|
35 | (1) |
|
|
36 | (2) |
|
Putting timing requirements into action |
|
|
38 | (1) |
|
2.2 Deployment of Fluentd |
|
|
38 | (8) |
|
Deploying Fluentd for the book's examples |
|
|
39 | (1) |
|
Deployment considerations for Fluentd |
|
|
39 | (1) |
|
Fluentd minimum footprint |
|
|
40 | (1) |
|
Simple deployment of Ruby |
|
|
40 | (1) |
|
Simple deployment of Fluentd |
|
|
41 | (3) |
|
Deploying a log generator |
|
|
44 | (2) |
|
|
46 | (1) |
|
2.3 Bringing Fluentd to life with "Hello World" |
|
|
46 | (4) |
|
|
46 | (1) |
|
"Hello World" configuration |
|
|
47 | (1) |
|
|
47 | (3) |
|
2.4 "Hello World" with Fluent Bit |
|
|
50 | (5) |
|
|
50 | (2) |
|
Alternate Fluent Bit startup options |
|
|
52 | (1) |
|
Fluent Bit configuration file comparison |
|
|
53 | (1) |
|
Fluent Bit configuration file in detail |
|
|
54 | (1) |
|
Putting the dummy plugin into action |
|
|
55 | (1) |
|
2.5 Fluentd deployment with Kubernetes and containers |
|
|
55 | (4) |
|
|
56 | (2) |
|
|
58 | (1) |
|
|
59 | (6) |
|
Installing Fluentd with UI |
|
|
59 | (6) |
|
|
65 | (100) |
|
3 Using Fluentd to capture log events |
|
|
67 | (26) |
|
3.1 Dry running to check a configuration |
|
|
68 | (1) |
|
Putting validating Fluentd configuration into action |
|
|
69 | (1) |
|
|
69 | (9) |
|
Putting the adaption of a Fluentd configuration to Fluent Bit into action |
|
|
70 | (1) |
|
Rereading and resuming reading of log files |
|
|
71 | (1) |
|
Configuration considerations for tracking position |
|
|
71 | (1) |
|
Wildcards in the path attribute |
|
|
72 | (1) |
|
|
73 | (1) |
|
Controlling the impact of wildcards in filenames |
|
|
73 | (2) |
|
Replacing wildcards with delimited lists in action |
|
|
75 | (1) |
|
|
75 | (3) |
|
|
78 | (3) |
|
|
78 | (3) |
|
3.4 Imposing structure on log events |
|
|
81 | (12) |
|
|
81 | (5) |
|
|
86 | (1) |
|
Applying a Regex parser to a complex log |
|
|
86 | (5) |
|
Putting parser configuration into action |
|
|
91 | (2) |
|
4 Using Fluentd to output log events |
|
|
93 | (26) |
|
|
94 | (9) |
|
|
94 | (1) |
|
|
95 | (3) |
|
Chunks and Controlling Buffering |
|
|
98 | (4) |
|
|
102 | (1) |
|
Putting configuring buffering size settings into action |
|
|
103 | (1) |
|
4.2 Output formatting options |
|
|
103 | (3) |
|
|
104 | (1) |
|
|
104 | (1) |
|
|
104 | (1) |
|
|
104 | (1) |
|
|
105 | (1) |
|
|
105 | (1) |
|
Putting JSON formatter configuration into action |
|
|
106 | (1) |
|
4.3 Sending log events to MongoDB |
|
|
106 | (5) |
|
Deploying MongoDB Fluentd plugin |
|
|
107 | (1) |
|
Configuring the Mongo output plugin for Fluentd |
|
|
108 | (3) |
|
Putting MongoDB connection configuration strings into action |
|
|
111 | (1) |
|
4.4 Actionable log events |
|
|
111 | (2) |
|
Actionable log events through service invocation |
|
|
112 | (1) |
|
Actionable through user interaction tools |
|
|
112 | (1) |
|
4.5 Slack to demonstrate the social output |
|
|
113 | (4) |
|
Handling tokens and credentials more carefully |
|
|
115 | (1) |
|
Externalizing Slack configuration attributes in action |
|
|
116 | (1) |
|
4.6 The right tool for the right job |
|
|
117 | (2) |
|
|
119 | (26) |
|
5.1 Reaching multiple outputs by copying |
|
|
120 | (6) |
|
Copy by reference or by value |
|
|
122 | (2) |
|
Handling errors when copying |
|
|
124 | (2) |
|
5.2 Configuration reuse and extension through inclusion |
|
|
126 | (4) |
|
Place holding with null output |
|
|
129 | (1) |
|
Putting inclusions with a MongoDB output into action |
|
|
129 | (1) |
|
5.3 Injecting context into log events |
|
|
130 | (2) |
|
|
131 | (1) |
|
|
132 | (4) |
|
|
135 | (1) |
|
Putting tag naming conventions into action |
|
|
135 | (1) |
|
Putting dynamic tagging with extract into action |
|
|
136 | (1) |
|
|
136 | (1) |
|
5.6 Labels: Taking tags to a new level |
|
|
137 | (8) |
|
Using a stdout filter to see what is happening |
|
|
137 | (1) |
|
Illustrating label and tag routing |
|
|
137 | (2) |
|
|
139 | (2) |
|
|
141 | (2) |
|
|
143 | (1) |
|
Putting a common pipeline into action |
|
|
144 | (1) |
|
6 Filtering and extrapolation |
|
|
145 | (20) |
|
6.1 Application of filters |
|
|
146 | (2) |
|
All is well events do not need to be distributed |
|
|
146 | (1) |
|
Spotting the needle in a haystack |
|
|
147 | (1) |
|
|
147 | (1) |
|
|
147 | (1) |
|
Unimplemented housekeeping |
|
|
148 | (1) |
|
6.2 Why change log events? |
|
|
148 | (2) |
|
Easier to process meaning downstream |
|
|
148 | (1) |
|
|
148 | (1) |
|
Record when we have reacted to a log event |
|
|
148 | (1) |
|
|
149 | (1) |
|
6.3 Applying filters and parsers |
|
|
150 | (7) |
|
|
150 | (1) |
|
|
150 | (3) |
|
Changing log events with the record_transformer plugin |
|
|
153 | (3) |
|
Filter parser vs. record transformer |
|
|
156 | (1) |
|
6.4 Demonstrating change impact with stdout in action |
|
|
157 | (1) |
|
A solution demonstrating change impact with stdout in action |
|
|
157 | (1) |
|
6.5 Extract to set key values |
|
|
157 | (2) |
|
6.6 Deriving new data values with the record_transformer |
|
|
159 | (1) |
|
Putting the incorporation of calculations into a log event transformation into action |
|
|
160 | (1) |
|
6.7 Generating simple Fluentd metrics |
|
|
160 | (5) |
|
Putting log event counting into action |
|
|
163 | (2) |
|
|
165 | (92) |
|
7 Performance and scaling |
|
|
167 | (30) |
|
7.1 Threading and processes to scale with workers |
|
|
168 | (5) |
|
|
169 | (2) |
|
|
171 | (1) |
|
Controlling output plugin threads |
|
|
172 | (1) |
|
Memory management optimization |
|
|
172 | (1) |
|
7.2 Scaling and moving workloads |
|
|
173 | (12) |
|
Fan-in/log aggregation and consolidation |
|
|
173 | (6) |
|
Fan-out and workload distribution |
|
|
179 | (5) |
|
|
184 | (1) |
|
Putting a high-availability comparison into action |
|
|
185 | (1) |
|
7.3 Fluentd scaling in containers vs. native and virtual environments |
|
|
185 | (5) |
|
Kubernetes worker node configuration |
|
|
186 | (1) |
|
Per-cluster configuration |
|
|
186 | (1) |
|
Container as visualization |
|
|
187 | (1) |
|
|
188 | (1) |
|
|
189 | (1) |
|
7.4 Securing traffic between Fluentd nodes |
|
|
190 | (2) |
|
|
190 | (1) |
|
TLS not just for encryption |
|
|
191 | (1) |
|
Certificate and private key storage |
|
|
191 | (1) |
|
Security is more than certificates |
|
|
192 | (1) |
|
7.5 Credentials management |
|
|
192 | (5) |
|
Simple credentials use case |
|
|
193 | (2) |
|
Putting certification into action |
|
|
195 | (2) |
|
8 Driving logs with Docker and Kubernetes |
|
|
197 | (34) |
|
8.1 Fluentd out of the box from Docker Hub |
|
|
198 | (2) |
|
|
198 | (1) |
|
|
199 | (1) |
|
Getting set up for Docker log drivers |
|
|
199 | (1) |
|
8.2 Using Docker log drivers |
|
|
200 | (7) |
|
Docker drivers via the command line |
|
|
200 | (1) |
|
A quick check of network connections |
|
|
201 | (1) |
|
Running Docker command line |
|
|
202 | (2) |
|
Switching to driver configuration through a configuration file |
|
|
204 | (3) |
|
8.3 Kubernetes components logging and the use of Fluentd |
|
|
207 | (2) |
|
Kubernetes components and structured logging |
|
|
208 | (1) |
|
Kubernetes default log retention and log rotation |
|
|
208 | (1) |
|
|
209 | (1) |
|
8.4 Demonstrating logging with Kubernetes |
|
|
209 | (10) |
|
|
210 | (2) |
|
|
212 | (3) |
|
Understanding how Fluentd DaemonSets are put together |
|
|
215 | (4) |
|
8.5 Getting a peek at host logs |
|
|
219 | (3) |
|
8.6 Configuring a Kubernetes logging DaemonSet |
|
|
222 | (6) |
|
Getting the Fluentd configuration ready to be used |
|
|
222 | (2) |
|
Creating our Kubernetes deployment configuration |
|
|
224 | (2) |
|
Putting the implementation of a Fluentd for Kubernetes into action |
|
|
226 | (1) |
|
|
227 | (1) |
|
|
228 | (1) |
|
8.7 Kubernetes configuration in action |
|
|
228 | (1) |
|
|
228 | (1) |
|
8.8 More Kubernetes monitoring and logging to watch for |
|
|
228 | (3) |
|
|
229 | (1) |
|
|
229 | (2) |
|
9 Creating custom plugins |
|
|
231 | (26) |
|
|
232 | (1) |
|
9.2 What is Redis, and why build a plugin with the Redis list capability? |
|
|
232 | (1) |
|
Redis list over RedisTimeSeries |
|
|
233 | (1) |
|
9.3 Illustrating our objective using Redis CLI |
|
|
233 | (1) |
|
9.4 Preparing for development |
|
|
234 | (1) |
|
|
235 | (3) |
|
Creating the skeleton plugin |
|
|
235 | (2) |
|
|
237 | (1) |
|
9.6 Implementing the plugin core |
|
|
238 | (6) |
|
How configuration attributes work |
|
|
238 | (2) |
|
Starting up and shutting down |
|
|
240 | (1) |
|
Getting the plugin to work with our Fluentd installation |
|
|
241 | (1) |
|
Putting additional configuration validation into action |
|
|
242 | (1) |
|
Implementing the Redis output logic |
|
|
243 | (1) |
|
Putting the testing of synchronous output into action |
|
|
244 | (1) |
|
9.7 Implementing the Redis input plugin |
|
|
244 | (3) |
|
Testing input and output plugin execution |
|
|
246 | (1) |
|
9.8 Extending output with buffering |
|
|
247 | (3) |
|
Improving our scenario by putting maintainability into action |
|
|
250 | (1) |
|
|
250 | (1) |
|
9.10 Putting the development of unit tests into action |
|
|
251 | (1) |
|
|
251 | (1) |
|
9.11 Package and deployment |
|
|
252 | (2) |
|
|
252 | (1) |
|
Complete metadata aka manifest |
|
|
253 | (1) |
|
|
253 | (1) |
|
Rerun without the plugin paths |
|
|
253 | (1) |
|
9.12 Extending to be an enterprise-class solution |
|
|
254 | (3) |
|
Part 4 Good logging practices and frameworks to maximize log value |
|
|
257 | (42) |
|
10 Logging best practices |
|
|
259 | (22) |
|
10.1 Audit events vs. log events |
|
|
260 | (1) |
|
10.2 Log levels and severities |
|
|
260 | (4) |
|
|
261 | (1) |
|
|
261 | (1) |
|
|
262 | (1) |
|
|
262 | (1) |
|
|
263 | (1) |
|
|
263 | (1) |
|
Extending or creating your own log levels |
|
|
263 | (1) |
|
|
264 | (1) |
|
10.4 Human and machine-readable |
|
|
265 | (1) |
|
|
265 | (4) |
|
|
266 | (1) |
|
|
266 | (1) |
|
|
266 | (1) |
|
|
267 | (1) |
|
|
268 | (1) |
|
A Practical checklist for capturing context |
|
|
268 | (1) |
|
|
269 | (2) |
|
|
271 | (1) |
|
Codes can be for more than errors |
|
|
271 | (1) |
|
10.7 Too little logging or too much? |
|
|
271 | (4) |
|
What qualifies as sensitive? |
|
|
272 | (2) |
|
|
274 | (1) |
|
10.8 Log structure and format |
|
|
275 | (2) |
|
Putting making log entries ready for application shipping into action |
|
|
276 | (1) |
|
10.9 Use frameworks if you can |
|
|
277 | (1) |
|
10.10 Development practices |
|
|
277 | (4) |
|
|
278 | (1) |
|
Using standard exceptions and error structures |
|
|
278 | (1) |
|
String construction as a reason not to log |
|
|
279 | (2) |
|
|
281 | (18) |
|
11.1 Value of logging frameworks |
|
|
282 | (1) |
|
11.2 Typical structure of a logging framework |
|
|
283 | (2) |
|
|
283 | (1) |
|
|
284 | (1) |
|
|
284 | (1) |
|
|
285 | (1) |
|
|
285 | (1) |
|
|
285 | (1) |
|
|
285 | (1) |
|
|
285 | (1) |
|
11.4 Logging framework landscape |
|
|
286 | (1) |
|
11.5 Choosing a framework |
|
|
287 | (1) |
|
Putting optimizing application logging into action |
|
|
288 | (1) |
|
11.6 Fluentd's own logging and appenders |
|
|
288 | (2) |
|
11.7 Illustrations of an application logging directly to Fluentd |
|
|
290 | (9) |
|
Python with logging framework: Using the Fluentd library |
|
|
290 | (3) |
|
Invoking Fluentd appender directly |
|
|
293 | (1) |
|
Illustration with only Python's logging |
|
|
294 | (1) |
|
Illustration without Python's logging or Fluentd library |
|
|
295 | (1) |
|
Porting the Fluentd calls to another language into action |
|
|
296 | (1) |
|
Using generic appenders: The takeaways |
|
|
297 | (2) |
Appendix A Installation of additional tools and services |
|
299 | (16) |
Appendix B Processing times and dates, regular expressions, and other configuration values |
|
315 | (6) |
Appendix C Plugins summary |
|
321 | (6) |
Appendix D Real-world use case |
|
327 | (10) |
Appendix E Useful resources |
|
337 | (16) |
Index |
|
353 | |