master
md 442 lines 23.6 KB
Rendered Raw
1 # NIDL Framework: Guiding Netdata's Observability
2
3 ## Introduction
4
5 The Netdata NIDL (Nodes, Instances, Dimensions, Labels) framework is the foundational data model that underpins Netdata's approach to observability. It defines how metrics are structured, collected, stored, and presented, enabling an interactive and intuitive analysis experience without the need for a query language.
6
7 For **users**, NIDL transforms raw data into an explorable, multi-dimensional view of their infrastructure. For **developers**, NIDL provides a strict set of guidelines for metric design, ensuring that collected data automatically translates into meaningful and actionable dashboards.
8
9 This document serves as both an introduction to the NIDL framework for all Netdata users and a fundamental guide for developers contributing to Netdata's data collection.
10
11 ## NIDL for Users: Interactive Observability
12
13 Imagine your infrastructure's performance data as a complex, multi-dimensional cube. Traditional monitoring tools often require you to learn a specialized query language to extract insights from this cube. Netdata, through the NIDL framework, provides intuitive controls to slice, dice, and examine this cube from any angle using simple dropdown menus.
14
15 ### The NIDL Components
16
17 Every metric collected by Netdata is organized according to these four components:
18
19 1. **Nodes**: Represent individual machines or hosts where Netdata agents are running. In a multi-node environment, this allows you to aggregate and compare metrics across your entire fleet.
20 2. **Instances**: Specific entities being monitored within a particular context. For example, in a `disk.io` chart, instances would be individual disk devices like `sda`, `sdb`. In a `containers.cpu` chart, instances would be individual container IDs or names.
21 3. **Dimensions**: The individual values or series that make up a chart. All dimensions within a single chart must share the same unit and represent related aspects of the monitored instance. For example, a CPU chart might have `user`, `system`, `iowait`, and `idle` as dimensions.
22 4. **Labels**: Key-value pairs that provide additional metadata about an instance or dimension. Labels enable powerful filtering and grouping capabilities. Examples include `kubernetes_namespace=production`, `device_type=ssd`, or `environment=staging`.
23
24 ### How to Use NIDL for Analysis
25
26 Every Netdata chart is an interactive analytical tool. Above each graph, you'll find dropdown menus corresponding to Nodes, Instances, Dimensions, and Labels. These menus are not just for filtering; they provide real-time statistics to guide your investigation:
27
28 ```
29 ┌───────────┬───────┬────────┬───────────┬────────────┬────────┬────────────┐
30 │ group by ▼│aggr. ▼│nodes ▼ │instances ▼│dimensions ▼│labels ▼│time aggr. ▼│
31 └───────────┴───────┴────────┴───────────┴────────────┴────────┴────────────┘
32 ┌───────────────────────────────────────────────────────────────────────────┐
33 │ ▒▒▒▒▒░░░▒▒▒▒▒▒░░░░▒▒▒ Anomaly ribbon (anomaly rates over time) │
34 ├───────────────────────────────────────────────────────────────────────────┤
35 │ ╱╲ ╱╲ │
36 │ ╱ ╲ ╱ ╲ GRAPH │
37 │ ╱ ╲╱ ╲ │
38 │ ╱ ╲_______________ │
39 ├───────────────────────────────────────────────────────────────────────────┤
40 │ ░░░░█░░░░░ Info ribbon (gaps, resets, partial data) │
41 └───────────────────────────────────────────────────────────────────────────┘
42 X-axis (time)
43 ─────────────────────────────────────────────────────────────────────────────
44 Dimension1: 12.3k │ Dimension2: 8.9k │ Dimension3: 5.6k │ Dimension4: 2.3k
45 ```
46
47 Each dropdown table displays:
48 * **Number of time-series**: How many individual data streams contribute to that item.
49 * **Number of instances**: The count of instances (relevant for Nodes, Dimensions, Labels dropdowns).
50 * **Volume contribution %**: The percentage of the total chart's value attributed to that item.
51 * **Anomaly rate %**: The percentage of time the item exhibited anomalous behavior within the visible window.
52 * **Minimum, Average, Maximum values**: Statistical summaries for the item over the visible period.
53
54 This rich context enables:
55
56 * **Instant Root Cause Analysis**: If you see a spike on a chart, open the "Instances" dropdown, sort by "Maximum Value," and immediately identify which specific instance (e.g., a container, a disk) is responsible. Similarly, sort by "Anomaly Rate" to pinpoint unusual behavior.
57 * **Flexible Grouping and Aggregation**: Change how the chart aggregates data. Group by `kubernetes_namespace` to see CPU usage per namespace, then apply an `average` aggregation to understand typical consumption.
58 * **Slicing and Filtering**: Select specific nodes, instances, or label values to narrow down the chart to only the data you care about.
59
60 ### NIDL Custom Dashboards
61
62 NIDL extends beyond individual charts to enable powerful custom dashboards through simple drag-and-drop operations:
63
64 * **Chart Reuse**: Any chart can appear multiple times on a custom dashboard with different NIDL settings
65 * **Visual Arrangement**: Resize and position charts to create meaningful layouts
66 * **Preserved Interactivity**: Each chart retains its full NIDL capabilities - filtering, grouping, and aggregation
67 * **Instant Creation**: No query writing or configuration files - just drag, drop, and customize
68
69 Example: Create a Kubernetes dashboard by dragging CPU, memory, and network charts, then setting one to group by namespace, another by pod, and a third showing node-level aggregations - all from the same underlying metrics.
70
71 ### Benefits of NIDL for Users
72
73 * **No Query Language Required**: Explore and analyze complex data through intuitive point-and-click interactions.
74 * **Automatic Visualization**: Every metric collected appears automatically on Netdata dashboards - if it's collected, it's visible. No manual dashboard configuration needed.
75 * **Speed of Investigation**: Real-time statistics and interactive controls allow for rapid diagnosis of issues.
76 * **Consistent Experience**: All Netdata charts operate under the same NIDL principles, making the interface predictable and easy to learn.
77 * **Custom Dashboard Simplicity**: Create powerful custom views through drag-and-drop, with each chart maintaining its full NIDL interactivity - no queries or configuration files required.
78 * **Scalability**: The framework works identically whether you're monitoring a single server or thousands of nodes.
79
80 ### Current Design Boundaries
81
82 NIDL makes deliberate UX choices to maintain simplicity and clarity. These aren't technical limitations - the query engine could handle more complexity - but rather design decisions that keep the interface intuitive:
83
84 1. **Uniform Aggregation per Chart**: All dimensions in a chart use the same aggregation function. For example, you cannot show "min of mins" and "max of maxes" in the same chart. This keeps the mental model simple: one chart, one aggregation.
85
86 2. **Single Context per Chart**: Each chart displays metrics from one context only. While the engine can query multiple contexts simultaneously, combining them would require complex UI controls that could overwhelm users.
87
88 3. **Continuous Evolution**: While NIDL controls already enhance and simplify advanced analytics for the vast majority of use cases, Netdata is continuously evolving. Like all monitoring solutions, we identify areas for improvement and actively work to address them.
89
90 ### Ongoing Enhancements
91
92 We've identified several areas where Netdata dashboards can be enhanced to cover even more sophisticated use cases without compromising NIDL's simplicity:
93
94 1. **Virtual Contexts**: Enable custom calculations across multiple contexts, appearing as new charts on dashboards - bringing complex correlations to the same simple interface
95
96 2. **Advanced Query Mode**: Introduce an optional query editor for power users, thoughtfully integrated to preserve the default NIDL experience
97
98 3. **Persistent Virtual Metrics**: Allow complex calculations to be saved as new time-series, making advanced analytics reusable and shareable
99
100 These improvements are part of Netdata's commitment to making infrastructure monitoring both powerful and accessible. We continuously refine the balance between capability and simplicity based on real-world usage and community feedback.
101
102 ## NIDL for Developers: The Engineering Discipline
103
104 For Netdata developers, understanding and adhering to the NIDL framework is paramount. In Netdata, **metric design IS dashboard design**. The choices made during data collection directly determine the usability and clarity of the automatically generated dashboards. There is no separate dashboard configuration step to correct poorly structured metrics.
105
106 ### Why Metric Design is Critical
107
108 * **Algorithmic Dashboards**: Netdata's dashboards are not static configurations; they are algorithmic outputs driven by the metadata embedded in your collected metrics. Your annotations guide this algorithm.
109 * **No Second Chances**: Mistakes in metric design cannot be easily rectified later through UI configuration. The integrity of the NIDL framework depends on correct data structuring at the source.
110 * **User Experience**: Your design decisions directly impact a user's ability to understand, troubleshoot, and gain insights from their infrastructure. Confusing charts lead to frustration and missed issues.
111
112 ### Core Principles for NIDL-Compliant Collectors
113
114 To ensure your collected metrics integrate seamlessly with the NIDL framework and produce meaningful charts, adhere to the following principles:
115
116 #### 1. One Instance Type Per Context
117
118 Each Netdata **context** (which corresponds to a single chart on the dashboard) must contain only one type of instance. Mixing different types of entities within the same context will lead to confusing dropdown menus and meaningless aggregations.
119
120 **Correct Example**:
121 ```
122 Context: mysql.db.queries
123 Instances: database1, database2, database3
124 Dimensions: select, insert, update, delete
125 ```
126 *Explanation*: All instances are of type "database".
127
128 **Incorrect Example**:
129 ```
130 Context: mysql.queries
131 Instances: server1, database1, table1 // Mixed instance types
132 Dimensions: select, insert, update, delete
133 ```
134 *Explanation*: Mixing server, database, and table instances in one context makes the "Instances" dropdown unusable for comparison or drill-down.
135
136 #### 2. Related Dimensions Only
137
138 All **dimensions** within a single chart (context) must be logically related, share the same unit, and make sense when aggregated together.
139
140 **Correct Example**:
141 ```
142 Context: system.cpu
143 Dimensions: user, system, iowait, idle
144 Unit: percentage
145 ```
146 *Explanation*: All dimensions represent parts of CPU time and sum to 100%.
147
148 **Incorrect Example**:
149 ```
150 Context: system.health
151 Dimensions: cpu_percent, free_memory_mb, disk_io_ops
152 ```
153 *Explanation*: These dimensions have different units and represent unrelated metrics, making aggregation or comparison within the same chart meaningless.
154
155 #### 3. Hierarchical Separation (Contexts, not Families for Instances)
156
157 For hierarchical data (e.g., a database server, its databases, its tables, its indexes), create **separate contexts** for each level of the hierarchy. Do not attempt to combine different hierarchical levels into a single context.
158
159 **Example: MySQL Monitoring**
160
161 Instead of one `mysql.operations` context trying to cover everything, create distinct contexts:
162
163 * `mysql.operations`: Instances are the database servers themselves.
164 * `mysql.db.operations`: Instances are individual databases (e.g., `users_db`, `orders_db`).
165 * `mysql.table.operations`: Instances are individual tables within databases.
166 * `mysql.index.operations`: Instances are individual indexes within tables.
167
168 Each of these contexts will generate its own chart, ensuring that the "Instances" dropdown for each chart is clean and coherent (e.g., the `mysql.db.operations` chart's "Instances" dropdown will only list databases, not servers or tables).
169
170 **Families** in Netdata are used to group *charts* (contexts) on the dashboard, not to define instance hierarchies within a single chart. You can use families to organize related contexts (e.g., a "MySQL" family containing all `mysql.*` contexts, or a "Connections" family grouping all connection-related contexts across different services).
171
172 #### 4. Thoughtful Labels
173
174 Use **labels** to provide meaningful metadata that enables flexible filtering and grouping. Labels should be consistent across instances and provide valuable context for analysis.
175
176 **Example**: For container metrics, useful labels might include:
177 * `kubernetes_pod_name`
178 * `kubernetes_namespace`
179 * `docker_image`
180 * `environment`
181
182 These labels allow users to slice their data by specific pods, namespaces, or environments, enhancing the analytical power of the chart.
183
184 ### Practical Examples of NIDL Design
185
186 #### Example 1: Disk I/O
187
188 **Context Design**:
189 * **Context**: `disk.io`
190 * **Instances**: `sda`, `sdb`, `sdc` (individual disk devices)
191 * **Dimensions**: `read`, `write` (bytes/s)
192 * **Labels**: `device_type=ssd`, `mount_point=/var`
193
194 **What this enables**: Users can compare I/O across disks, see read/write patterns per disk, filter by device type, and group by mount point.
195
196 #### Example 2: Container Monitoring
197
198 **Context Design**:
199 * **Context**: `containers.cpu`
200 * **Instances**: `container1`, `container2`, `container3` (individual containers)
201 * **Dimensions**: `user`, `system` (percentage)
202 * **Labels**: `image=nginx`, `namespace=production`, `pod=web-server`
203
204 **What this enables**: Users can compare CPU usage across containers, identify system vs. user CPU consumption, filter by image type, and group by Kubernetes namespace or pod.
205
206 #### Example 3: Application Metrics (Separation of Concerns)
207
208 Instead of one generic metric, separate by concerns and hierarchical levels:
209
210 * **Context**: `app.requests`
211 * **Instances**: `endpoint1`, `endpoint2`
212 * **Dimensions**: `success`, `client_error`, `server_error` (requests/s)
213 * **Context**: `app.response_time`
214 * **Instances**: `endpoint1`, `endpoint2`
215 * **Dimensions**: `p50`, `p95`, `p99` (milliseconds)
216 * **Context**: `app.active_connections`
217 * **Instances**: `server1`, `server2`
218 * **Dimensions**: `active`, `idle` (connections)
219
220 ### NIDL and Data Ingestion
221
222 When ingesting metrics from other observability solutions (e.g., Prometheus), it's common to encounter multi-dimensional metrics that combine several instance types or hierarchical levels into a single metric.
223
224 **Prometheus-style (example)**:
225 `mysql_operations{server="prod1", database="db1", table="users", operation="read"} = 1234`
226
227 This single metric contains enough information to extract server-level, database-level, and table-level views. With NIDL, you could technically import this as-is and use the dropdown menus to aggregate by different labels.
228
229 **However, this misses the bigger picture of dashboard design**.
230
231 Consider how you'd structure a dashboard if designing it by hand:
232 - **Server section**: Server health, total load, overall performance
233 - **Database section**: Per-database metrics like connections, table count, size, plus aggregated performance from tables
234 - **Table section**: Detailed table-level operations, row counts, index usage
235
236 Each section tells its own story with metrics appropriate to that level.
237
238 **Netdata's Best Practice**: Create this natural structure through separate contexts:
239
240 * `mysql.operations` - Server-level view with server-specific metrics
241 * `mysql.db.operations` - Database-level view combining:
242 - Native database metrics (connections, table count)
243 - Pre-aggregated table metrics for this level
244 * `mysql.table.operations` - Detailed table-level metrics
245
246 This approach delivers:
247 * **Intuitive dashboard structure** - Users immediately understand what each section represents
248 * **Complete metrics at each level** - Not just aggregations, but level-specific insights
249 * **Natural navigation** - From overview (server) to specific (tables)
250 * **Clear mental model** - Each chart answers questions appropriate to its level
251
252 The key insight: Pre-aggregation isn't just about performance - it's about creating a well-structured dashboard where each section has a clear purpose and tells a complete story.
253
254 ### Practical Guide: Designing NIDL-Compliant Collectors
255
256 This guide walks through the thought process of designing metrics for a new collector, using database servers (PostgreSQL) and application servers (WebSphere) as examples.
257
258 #### Step 1: Identify Key Components and Characteristics
259
260 **Question to answer**: What are the major functional areas of this application that need monitoring?
261
262 **Example - PostgreSQL**:
263 - Server health & connections
264 - Query performance
265 - Database operations
266 - Table operations
267 - Replication status
268 - Storage engine internals
269
270 **Example - WebSphere**:
271 - JVM health (memory, GC, threads)
272 - Web container (servlets, sessions, JSP)
273 - Connection pools (JDBC, JMS)
274 - Message queuing
275 - Security & transactions
276
277 #### Step 2: Organize into Families
278
279 **Decision**: Flat structure (\<10 families) or Tree structure (\>10 families)?
280
281 **PostgreSQL - Flat Structure**:
282 ```
283 connections
284 queries
285 databases
286 tables
287 replication
288 ```
289
290 **WebSphere - Tree Structure**:
291 ```
292 jvm/memory
293 jvm/gc
294 jvm/threads
295 web/servlets
296 web/sessions
297 connections/jdbc
298 connections/jms
299 ```
300
301 **Rules**:
302 - No family can have both charts and subfamilies
303 - Use "overview" only for metrics that don't fit subfamilies
304 - Each leaf should have 3+ charts to justify existence
305
306 #### Step 3: Validate Metric Belonging and Instance Consistency
307
308 For each family/subfamily:
309
310 1. **List all metrics** that belong here
311 2. **Verify they're all about the same thing** (e.g., all about servlets)
312 3. **Identify the instance type** for each metric
313 4. **Ensure 90%+ share the same instance definition**
314
315 **Example - web/servlets**:
316 ```
317 ✓ servlet.requests → Instance: each servlet
318 ✓ servlet.response_time → Instance: each servlet
319 ✓ servlet.errors → Instance: each servlet
320 ? servlet.total_count → Instance: server (put first as summary)
321 ✗ session.count → Wrong topic! (move to web/sessions)
322 ```
323
324 #### Step 4: Group Metrics into Contexts
325
326 For each group of related metrics with the same instance type:
327
328 1. **Identify shared characteristics**:
329 - Same unit of measurement
330 - Related dimensions that sum meaningfully
331 - Tell one coherent story
332
333 2. **Create contexts**:
334
335 **Example - PostgreSQL Tables**:
336 ```
337 Context: postgres.table.operations
338 Instances: users_table, orders_table, products_table
339 Dimensions: select, insert, update, delete
340 Unit: operations/s
341 Title: "Table Operations"
342
343 Context: postgres.table.size
344 Instances: users_table, orders_table, products_table
345 Dimensions: size, indexes_size
346 Unit: bytes
347 Title: "Table Size"
348 ```
349
350 **Common mistake to avoid**:
351 ```
352 WRONG - Mixed dimensions per instance:
353 Context: postgres.table.operations
354 Instance: users_table → Dimensions: select, insert, update
355 Instance: orders_table → Dimensions: select, delete // Missing insert, update!
356 ```
357
358 #### Step 5: Validate Context Design
359
360 For each context, verify:
361
362 - [ ] **One instance type** (don't mix tables with databases)
363 - [ ] **One unit** (don't mix bytes with operations/s)
364 - [ ] **Consistent dimensions** across all instances
365 - [ ] **Meaningful aggregations** (summing dimensions makes sense)
366 - [ ] **Clear title** that explains what's being measured
367
368 #### Step 6: Handle Edge Cases
369
370 **Summary metrics** (different instance type):
371 - Place at the beginning of the section
372 - Or move to parent/overview section
373
374 **Rate metrics**:
375 - Always specify time unit: "requests/s", not "requests"
376 - Use Incremental algorithm on raw counters
377
378 **Complex hierarchies**:
379 - Create separate contexts for each level
380 - Pre-aggregate at collection time
381 - Don't rely on query-time aggregation
382
383 #### Complete Example: PostgreSQL Tables Section
384
385 ```
386 Family: tables
387
388 1. postgres.table.count
389 Instance: server
390 Dimensions: total_tables
391 Unit: tables
392 Title: "Total Tables"
393 (Summary chart - goes first)
394
395 2. postgres.table.operations
396 Instances: each table
397 Dimensions: select, insert, update, delete
398 Unit: operations/s
399 Title: "Table Operations"
400
401 3. postgres.table.size
402 Instances: each table
403 Dimensions: data_size, indexes_size
404 Unit: bytes
405 Title: "Table Size"
406
407 4. postgres.table.maintenance
408 Instances: each table
409 Dimensions: vacuum_time, analyze_time
410 Unit: seconds
411 Title: "Table Maintenance"
412 ```
413
414 #### Final Checklist
415
416 - [ ] Each family represents a major functional area
417 - [ ] Navigation structure is intuitive (\<10 flat, \>10 tree)
418 - [ ] All metrics in a family are about the same topic
419 - [ ] Each context has consistent instance types
420 - [ ] All instances in a context have identical dimensions
421 - [ ] Units are consistent within each context
422 - [ ] Summary metrics are properly positioned
423 - [ ] Rate metrics include time units
424 - [ ] Chart titles clearly describe what's measured
425
426 Following this guide ensures your collector creates a coherent, navigable dashboard that tells clear stories about each aspect of the monitored application.
427
428 ### The Role of Netdata's Storage Efficiency
429
430 Netdata's highly efficient storage engine (0.5 bytes per sample on the high-resolution tier) is crucial for the NIDL framework's success. This efficiency allows Netdata to:
431
432 * **Collect data at multiple levels** (e.g., server, database, table) without significant storage penalties.
433 * **Pre-summarize at collection time**, rather than relying on expensive query-time aggregations.
434 * **Maintain full granularity** at each level, ensuring no loss of detail.
435
436 This means that the NIDL discipline of creating separate contexts for each level is not just about clarity; it's also a performance optimization. By doing the "heavy lifting" once at collection time, Netdata ensures fast dashboards and instant responses for users.
437
438 ## Conclusion
439
440 The NIDL framework is the backbone of Netdata's "no query language needed" philosophy. It empowers users with intuitive, interactive data exploration capabilities. However, this power comes with a critical responsibility for developers: to design metrics thoughtfully and adhere strictly to NIDL principles.
441
442 By embracing the NIDL framework, collector developers are not merely writing data collection code; they are designing the entire observability experience. Their discipline in defining coherent contexts, consistent instances, related dimensions, and meaningful labels directly translates into clear, actionable, and automatically generated dashboards that empower every Netdata user.