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 ```