| 1 | # agent |
| 2 | |
| 3 | This library is a tool for writing [netdata](https://github.com/netdata/netdata) plugins. |
| 4 | |
| 5 | We strongly believe that custom plugins are very important, and they must be easy to write. |
| 6 | |
| 7 | |
| 8 | Definitions: |
| 9 | - orchestrator |
| 10 | > plugin orchestrators are external plugins that do not collect any data by themselves. Instead, they support data collection modules written in the language of the orchestrator. Usually the orchestrator provides a higher level abstraction, making it ideal for writing new data collection modules with the minimum of code. |
| 11 | |
| 12 | - plugin |
| 13 | > plugin is a set of data collection modules. |
| 14 | |
| 15 | - module |
| 16 | > module is a data collector. It collects, processes and returns processed data to the orchestrator. |
| 17 | |
| 18 | - job |
| 19 | > job is a module instance with specific settings. |
| 20 | |
| 21 | |
| 22 | Package provides: |
| 23 | - CLI parser |
| 24 | - plugin orchestrator (loads configurations, creates and serves jobs) |
| 25 | |
| 26 | You are responsible only for __creating modules__. |
| 27 | |
| 28 | ## Architecture Boundaries |
| 29 | |
| 30 | The `agent` package is framework/core orchestration only. |
| 31 | |
| 32 | - `src/go/plugin/agent/**`: context-driven orchestration and adapter contracts. |
| 33 | - `src/go/cmd/*`: composition root and process host responsibilities: |
| 34 | - signal handling / exits / keepalive lifecycle |
| 35 | - module registry selection |
| 36 | - discovery provider wiring and policy selection |
| 37 | - Provider implementations (for example go.d SD discoverers) are selected explicitly in `cmd` wiring, not by implicit imports in `agent`. |
| 38 | |
| 39 | ## Custom plugin example |
| 40 | |
| 41 | [Yep! So easy!](https://github.com/netdata/netdata/blob/master/src/go/plugin/go.d/examples/simple/main.go) |
| 42 | |
| 43 | ## How to write a Module |
| 44 | |
| 45 | Module is responsible for **charts creating** and **data collecting**. Implement Module interface and that is it. |
| 46 | |
| 47 | ```go |
| 48 | type Module interface { |
| 49 | // Init does initialization. |
| 50 | // If it returns false, the job will be disabled. |
| 51 | Init() bool |
| 52 | |
| 53 | // Check is called after Init. |
| 54 | // If it returns false, the job will be disabled. |
| 55 | Check() bool |
| 56 | |
| 57 | // Charts returns the chart definition. |
| 58 | // Make sure not to share returned instance. |
| 59 | Charts() *Charts |
| 60 | |
| 61 | // Collect collects metrics. |
| 62 | Collect() map[string]int64 |
| 63 | |
| 64 | // SetLogger sets logger. |
| 65 | SetLogger(l *logger.Logger) |
| 66 | |
| 67 | // Cleanup performs cleanup if needed. |
| 68 | Cleanup() |
| 69 | } |
| 70 | |
| 71 | // Base is a helper struct. All modules should embed this struct. |
| 72 | type Base struct { |
| 73 | *logger.Logger |
| 74 | } |
| 75 | |
| 76 | // SetLogger sets logger. |
| 77 | func (b *Base) SetLogger(l *logger.Logger) { b.Logger = l } |
| 78 | |
| 79 | ``` |
| 80 | |
| 81 | ## How to write a Plugin |
| 82 | |
| 83 | Since plugin is a set of modules all you need is: |
| 84 | - write module(s) |
| 85 | - add module(s) to the plugins [registry](https://github.com/netdata/netdata/blob/master/src/go/plugin/go.d/plugin/module/registry.go) |
| 86 | - start the plugin |
| 87 | |
| 88 | |
| 89 | ## How to integrate your plugin into Netdata |
| 90 | |
| 91 | Three simple steps: |
| 92 | - move the plugin to the `plugins.d` dir. |
| 93 | - add plugin configuration file to the `etc/netdata/` dir. |
| 94 | - add modules configuration files to the `etc/netdata/<DIR_NAME>/` dir. |
| 95 | |
| 96 | Congratulations! |
| 97 | |
| 98 | ## Configurations |
| 99 | |
| 100 | Configurations are written in [YAML](https://yaml.org/). |
| 101 | |
| 102 | - plugin configuration: |
| 103 | |
| 104 | ```yaml |
| 105 | |
| 106 | # Enable/disable the whole plugin. |
| 107 | enabled: yes |
| 108 | |
| 109 | # Default enable/disable value for all modules. |
| 110 | default_run: yes |
| 111 | |
| 112 | # Maximum number of used CPUs. Zero means no limit. |
| 113 | max_procs: 0 |
| 114 | |
| 115 | # Enable/disable specific plugin module |
| 116 | modules: |
| 117 | # module_name1: yes |
| 118 | # module_name2: yes |
| 119 | |
| 120 | ``` |
| 121 | |
| 122 | - module configuration |
| 123 | |
| 124 | ```yaml |
| 125 | # [ GLOBAL ] |
| 126 | update_every: 1 |
| 127 | autodetection_retry: 0 |
| 128 | |
| 129 | # [ JOBS ] |
| 130 | jobs: |
| 131 | - name: job1 |
| 132 | param1: value1 |
| 133 | param2: value2 |
| 134 | |
| 135 | - name: job2 |
| 136 | param1: value1 |
| 137 | param2: value2 |
| 138 | ``` |
| 139 | |
| 140 | Plugin uses `yaml.Unmarshal` to add configuration parameters to the module. Please use `yaml` tags! |
| 141 | |
| 142 | ## Debug |
| 143 | |
| 144 | Plugin CLI: |
| 145 | ``` |
| 146 | Usage: |
| 147 | plugin [OPTIONS] [update every] |
| 148 | |
| 149 | Application Options: |
| 150 | -d, --debug debug mode |
| 151 | -m, --modules= modules name (default: all) |
| 152 | -c, --config= config dir |
| 153 | |
| 154 | Help Options: |
| 155 | -h, --help Show this help message |
| 156 | |
| 157 | ``` |
| 158 | |
| 159 | Specific module debug: |
| 160 | ``` |
| 161 | # become user netdata |
| 162 | sudo su -s /bin/bash netdata |
| 163 | |
| 164 | # run plugin in debug mode |
| 165 | ./<plugin_name> -d -m <module_name> |
| 166 | ``` |
| 167 | |
| 168 | Change `<plugin_name>` to your plugin name and `<module_name>` to the module name you want to debug. |