github.com/Jeffail/benthos/v3@v3.65.0/lib/output/docs.go (about)

     1  package output
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/Jeffail/benthos/v3/internal/docs"
    10  	"github.com/Jeffail/benthos/v3/lib/util/config"
    11  )
    12  
    13  // DocsBatches returns a documentation paragraph regarding outputs that support
    14  // batching.
    15  var DocsBatches = `
    16  This output benefits from sending messages as a batch for improved performance.
    17  Batches can be formed at both the input and output level. You can find out more
    18  [in this doc](/docs/configuration/batching).`
    19  
    20  // DocsAsync returns a documentation paragraph regarding outputs that support
    21  // asynchronous sends.
    22  var DocsAsync = `
    23  This output benefits from sending multiple messages in flight in parallel for
    24  improved performance. You can tune the max number of in flight messages with the
    25  field ` + "`max_in_flight`" + `.`
    26  
    27  var header = "This document was generated with `benthos --list-outputs`" + `
    28  
    29  An output is a sink where we wish to send our consumed data after applying an
    30  optional array of [processors](/docs/components/processors/about). Only one output is configured at
    31  the root of a Benthos config. However, the output can be a [broker](/docs/components/outputs/broker)
    32  which combines multiple outputs under a chosen brokering pattern.
    33  
    34  An output config section looks like this:
    35  
    36  ` + "``` yaml" + `
    37  output:
    38    s3:
    39      bucket: TODO
    40      path: "${!meta(\"kafka_topic\")}/${!json(\"message.id\")}.json"
    41  
    42    # Optional list of processing steps
    43    processors:
    44     - jmespath:
    45         query: '{ message: @, meta: { link_count: length(links) } }'
    46  ` + "```" + `
    47  
    48  ### Back Pressure
    49  
    50  Benthos outputs apply back pressure to components upstream. This means if your
    51  output target starts blocking traffic Benthos will gracefully stop consuming
    52  until the issue is resolved.
    53  
    54  ### Retries
    55  
    56  When a Benthos output fails to send a message the error is propagated back up to
    57  the input, where depending on the protocol it will either be pushed back to the
    58  source as a Noack (e.g. AMQP) or will be reattempted indefinitely with the
    59  commit withheld until success (e.g. Kafka).
    60  
    61  It's possible to instead have Benthos indefinitely retry an output until success
    62  with a [` + "`retry`" + `](/docs/components/outputs/retry) output. Some other outputs, such as the
    63  [` + "`broker`" + `](/docs/components/outputs/broker), might also retry indefinitely depending on their
    64  configuration.
    65  
    66  ### Multiplexing Outputs
    67  
    68  It is possible to perform content based multiplexing of messages to specific
    69  outputs either by using the ` + "[`switch`](/docs/components/outputs/switch)" + ` output, or a
    70  ` + "[`broker`](/docs/components/outputs/broker)" + ` with the ` + "`fan_out`" + ` pattern and a
    71  [filter processor](/docs/components/processors/filter_parts) on each output, which
    72  is a processor that drops messages if the condition does not pass.
    73  Conditions are content aware logical operators that can be combined using
    74  boolean logic.
    75  
    76  For more information regarding conditions, including a full list of available
    77  conditions please [read the docs here](/docs/components/conditions/about).
    78  
    79  ### Dead Letter Queues
    80  
    81  It's possible to create fallback outputs for when an output target fails using
    82  a ` + "[`try`](/docs/components/outputs/try)" + ` output.`
    83  
    84  // Descriptions returns a formatted string of collated descriptions of each
    85  // type.
    86  func Descriptions() string {
    87  	// Order our output types alphabetically
    88  	names := []string{}
    89  	for name := range Constructors {
    90  		names = append(names, name)
    91  	}
    92  	sort.Strings(names)
    93  
    94  	buf := bytes.Buffer{}
    95  	buf.WriteString("Outputs\n")
    96  	buf.WriteString(strings.Repeat("=", 7))
    97  	buf.WriteString("\n\n")
    98  	buf.WriteString(header)
    99  	buf.WriteString("\n\n")
   100  
   101  	buf.WriteString("### Contents\n\n")
   102  	i := 0
   103  	for _, name := range names {
   104  		if Constructors[name].Status == docs.StatusDeprecated {
   105  			continue
   106  		}
   107  		i++
   108  		buf.WriteString(fmt.Sprintf("%v. [`%v`](#%v)\n", i, name, name))
   109  	}
   110  	buf.WriteString("\n")
   111  
   112  	// Append each description
   113  	for i, name := range names {
   114  		def := Constructors[name]
   115  		if def.Status == docs.StatusDeprecated {
   116  			continue
   117  		}
   118  
   119  		var confBytes []byte
   120  
   121  		conf := NewConfig()
   122  		conf.Type = name
   123  		if confSanit, err := conf.Sanitised(true); err == nil {
   124  			confBytes, _ = config.MarshalYAML(confSanit)
   125  		}
   126  
   127  		buf.WriteString("## ")
   128  		buf.WriteString("`" + name + "`")
   129  		buf.WriteString("\n")
   130  		if confBytes != nil {
   131  			buf.WriteString("\n``` yaml\n")
   132  			buf.Write(confBytes)
   133  			buf.WriteString("```\n")
   134  		}
   135  		buf.WriteString(def.Description)
   136  
   137  		hasPerformanced := false
   138  		performance := func() {
   139  			if !hasPerformanced {
   140  				buf.WriteString("\n\n### Performance\n")
   141  				hasPerformanced = true
   142  			} else {
   143  				buf.WriteString("\n")
   144  			}
   145  		}
   146  		if def.Async {
   147  			performance()
   148  			buf.WriteString(`
   149  This output benefits from sending multiple messages in flight in parallel for
   150  improved performance. You can tune the max number of in flight messages with the
   151  field ` + "`max_in_flight`" + `.`)
   152  		}
   153  		if def.Batches {
   154  			performance()
   155  			buf.WriteString(`
   156  This output benefits from sending messages as a batch for improved performance.
   157  Batches can be formed at both the input and output level. You can find out more
   158  [in this doc](/docs/configuration/batching).`)
   159  		}
   160  		buf.WriteString("\n")
   161  		if i != (len(names) - 1) {
   162  			buf.WriteString("\n---\n")
   163  		}
   164  	}
   165  	return buf.String()
   166  }
   167  
   168  //------------------------------------------------------------------------------