github.com/influxdata/telegraf@v1.30.3/docs/PROCESSORS.md (about)

     1  # Processor Plugins
     2  
     3  This section is for developers who want to create a new processor plugin.
     4  
     5  ## Processor Plugin Guidelines
     6  
     7  * A processor must conform to the [telegraf.Processor][] interface.
     8  * Processors should call `processors.Add` in their `init` function to register
     9    themselves.  See below for a quick example.
    10  * To be available within Telegraf itself, plugins must register themselves
    11    using a file in `github.com/influxdata/telegraf/plugins/processors/all`
    12    named according to the plugin name. Make sure you also add build-tags to
    13    conditionally build the plugin.
    14  * Each plugin requires a file called `sample.conf` containing the sample
    15    configuration  for the plugin in TOML format.
    16    Please consult the [Sample Config][] page for the latest style guidelines.
    17  * Each plugin `README.md` file should include the `sample.conf` file in a
    18    section describing the configuration by specifying a `toml` section in the
    19    form `toml @sample.conf`. The specified file(s) are then injected
    20    automatically into the Readme.
    21  * Follow the recommended [Code Style][].
    22  
    23  [Sample Config]: /docs/developers/SAMPLE_CONFIG.md
    24  [Code Style]: /docs/developers/CODE_STYLE.md
    25  [telegraf.Processor]: https://godoc.org/github.com/influxdata/telegraf#Processor
    26  
    27  ## Streaming Processors
    28  
    29  Streaming processors are a new processor type available to you. They are
    30  particularly useful to implement processor types that use background processes
    31  or goroutines to process multiple metrics at the same time. Some examples of
    32  this are the execd processor, which pipes metrics out to an external process
    33  over stdin and reads them back over stdout, and the reverse_dns processor, which
    34  does reverse dns lookups on IP addresses in fields. While both of these come
    35  with a speed cost, it would be significantly worse if you had to process one
    36  metric completely from start to finish before handling the next metric, and thus
    37  they benefit significantly from a streaming-pipe approach.
    38  
    39  Some differences from classic Processors:
    40  
    41  * Streaming processors must conform to the [telegraf.StreamingProcessor][] interface.
    42  * Processors should call `processors.AddStreaming` in their `init` function to register
    43    themselves.  See below for a quick example.
    44  
    45  [telegraf.StreamingProcessor]: https://godoc.org/github.com/influxdata/telegraf#StreamingProcessor
    46  
    47  ## Processor Plugin Example
    48  
    49  ### Registration
    50  
    51  Registration of the plugin on `plugins/processors/all/printer.go`:
    52  
    53  ```go
    54  //go:build !custom || processors || processors.printer
    55  
    56  package all
    57  
    58  import _ "github.com/influxdata/telegraf/plugins/processors/printer" // register plugin
    59  ```
    60  
    61  The _build-tags_ in the first line allow to selectively include/exclude your
    62  plugin when customizing Telegraf.
    63  
    64  ### Plugin
    65  
    66  Content of your plugin file e.g. `printer.go`
    67  
    68  ```go
    69  //go:generate ../../../tools/readme_config_includer/generator
    70  package printer
    71  
    72  import (
    73      _ "embed"
    74      "fmt"
    75  
    76      "github.com/influxdata/telegraf"
    77      "github.com/influxdata/telegraf/plugins/processors"
    78  )
    79  
    80  //go:embed sample.conf
    81  var sampleConfig string
    82  
    83  type Printer struct {
    84      Log telegraf.Logger `toml:"-"`
    85  }
    86  
    87  func (*Printer) SampleConfig() string {
    88      return sampleConfig
    89  }
    90  
    91  // Init is for setup, and validating config.
    92  func (p *Printer) Init() error {
    93      return nil
    94  }
    95  
    96  func (p *Printer) Apply(in ...telegraf.Metric) []telegraf.Metric {
    97      for _, metric := range in {
    98          fmt.Println(metric.String())
    99      }
   100      return in
   101  }
   102  
   103  func init() {
   104      processors.Add("printer", func() telegraf.Processor {
   105          return &Printer{}
   106      })
   107  }
   108  ```
   109  
   110  ## Streaming Processor Example
   111  
   112  ```go
   113  //go:generate ../../../tools/readme_config_includer/generator
   114  package printer
   115  
   116  import (
   117      _ "embed"
   118      "fmt"
   119  
   120      "github.com/influxdata/telegraf"
   121      "github.com/influxdata/telegraf/plugins/processors"
   122  )
   123  
   124  //go:embed sample.conf
   125  var sampleConfig string
   126  
   127  type Printer struct {
   128      Log telegraf.Logger `toml:"-"`
   129  }
   130  
   131  func (*Printer) SampleConfig() string {
   132      return sampleConfig
   133  }
   134  
   135  // Init is for setup, and validating config.
   136  func (p *Printer) Init() error {
   137      return nil
   138  }
   139  
   140  // Start is called once when the plugin starts; it is only called once per
   141  // plugin instance, and never in parallel.
   142  // Start should return once it is ready to receive metrics.
   143  // The passed in accumulator is the same as the one passed to Add(), so you
   144  // can choose to save it in the plugin, or use the one received from Add().
   145  func (p *Printer) Start(acc telegraf.Accumulator) error {
   146  }
   147  
   148  // Add is called for each metric to be processed. The Add() function does not
   149  // need to wait for the metric to be processed before returning, and it may
   150  // be acceptable to let background goroutine(s) handle the processing if you
   151  // have slow processing you need to do in parallel.
   152  // Keep in mind Add() should not spawn unbounded goroutines, so you may need
   153  // to use a semaphore or pool of workers (eg: reverse_dns plugin does this).
   154  // Metrics you don't want to pass downstream should have metric.Drop() called,
   155  // rather than simply omitting the acc.AddMetric() call
   156  func (p *Printer) Add(metric telegraf.Metric, acc telegraf.Accumulator) error {
   157      // print!
   158      fmt.Println(metric.String())
   159      // pass the metric downstream, or metric.Drop() it.
   160      // Metric will be dropped if this function returns an error.
   161      acc.AddMetric(metric)
   162  
   163      return nil
   164  }
   165  
   166  // Stop gives you an opportunity to gracefully shut down the processor.
   167  // Once Stop() is called, Add() will not be called any more. If you are using
   168  // goroutines, you should wait for any in-progress metrics to be processed
   169  // before returning from Stop().
   170  // When stop returns, you should no longer be writing metrics to the
   171  // accumulator.
   172  func (p *Printer) Stop() error {
   173  }
   174  
   175  func init() {
   176      processors.AddStreaming("printer", func() telegraf.StreamingProcessor {
   177          return &Printer{}
   178      })
   179  }
   180  ```