github.com/observiq/carbon@v0.9.11-0.20200820160507-1b872e368a5e/CONTRIBUTING.md (about)

     1  # Contributing to Carbon
     2  
     3  ## Development
     4  
     5  You can view and edit the source code by cloning this repository:
     6  
     7  ```bash
     8  git clone https://github.com/observiq/carbon.git
     9  ```
    10  ## Pull Requests
    11  
    12  ### How to Send Pull Requests
    13  
    14  Everyone is welcome to contribute code to `carbon` via
    15  GitHub pull requests (PRs).
    16  
    17  To create a new PR, fork the project in GitHub and clone the upstream
    18  repo:
    19  
    20  ```sh
    21  $ go get -d github.com/observiq/carbon
    22  ```
    23  
    24  This will put the project in `${GOPATH}/src/github.com/observiq/carbon`. You
    25  can alternatively use `git` directly with:
    26  
    27  ```sh
    28  $ git clone https://github.com/observiq/carbon
    29  ```
    30  
    31  This would put the project in the `carbon` directory in
    32  current working directory.
    33  
    34  Enter the newly created directory and add your fork as a new remote:
    35  
    36  ```sh
    37  $ git remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-go
    38  ```
    39  
    40  Check out a new branch, make modifications, run linters and tests, and
    41  push the branch to your fork:
    42  
    43  ```sh
    44  $ git checkout -b <YOUR_BRANCH_NAME>
    45  # edit files
    46  $ go test -race ./...
    47  $ git add -p
    48  $ git commit
    49  $ git push <YOUR_FORK> <YOUR_BRANCH_NAME>
    50  ```
    51  
    52  Open a pull request against the main `carbon` repo.
    53  
    54  ### How to Receive Comments
    55  
    56  * If the PR is not ready for review, please put `[WIP]` in the title,
    57    tag it as `work-in-progress`, or mark it as
    58    [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
    59  * Make sure CI passes.
    60  
    61  ### How to Get PRs Merged
    62  
    63  A PR is considered to be **ready to merge** when:
    64  
    65  * It has received approval from at least one maintainer.
    66  * CI passes.
    67  * Major feedback is resolved.
    68  
    69  ## Design Choices
    70  
    71  Best practices for developing a builtin operator are documented below, but for changes to
    72  the core agent, we are happy to discuss proposals in the issue tracker.
    73  
    74  ### Builtin Operator Development
    75  
    76  In order to write a builtin operator, follow these three steps:
    77  1. Build a unique struct that satisfies the [`Operator`](operator/operator.go) interface. This struct will define what your operator does when executed in the pipeline.
    78  
    79  ```go
    80  type ExampleOperator struct {
    81  	FilePath string
    82  }
    83  
    84  func (p *ExampleOperator) Process(ctx context.Context, entry *entry.Entry) error {
    85  	// Processing logic
    86  }
    87  ```
    88  
    89  2. Build a unique config struct that satisfies the [`Config`](operator/config.go) interface. This struct will define the parameters used to configure and build your operator struct in step 1.
    90  
    91  ```go
    92  type ExampleOperatorConfig struct {
    93  	filePath string
    94  }
    95  
    96  func (c ExampleOperatorConfig) Build(context operator.BuildContext) (operator.Operator, error) {
    97  	return &ExampleOperator{
    98  		filePath: c.FilePath,
    99  	}, nil
   100  }
   101  ```
   102  
   103  3. Register your config struct in the operator registry using an `init()` hook. This will ensure that the agent knows about your operator at runtime and can build it from a YAML config.
   104  
   105  ```go
   106  func init() {
   107  	operator.Register("example_operator", &ExampleOperatorConfig{})
   108  }
   109  ```
   110  
   111  ## Any tips for building operators?
   112  We highly recommend that developers take advantage of [helpers](operator/helper) when building their operators. Helpers are structs that help satisfy common behavior shared across many operators. By embedding these structs, you can skip having to satisfy certain aspects of the `operator` and `config` interfaces.
   113  
   114  For example, almost all operators should embed the [BasicOperator](operator/helper/basic_operator.go) helper, as it provides simple functionality for returning an operator id and operator type.
   115  
   116  ```go
   117  // ExampleOperator is a basic operator, with a basic lifecycle, that consumes
   118  // but doesn't send log entries. Rather than implementing every part of the operator
   119  // interface, we can embed the following helpers to achieve this effect.
   120  type ExampleOperator struct {
   121  	helper.BasicOperator
   122  	helper.BasicLifecycle
   123  	helper.BasicOutput
   124  }
   125  ```