Skip to content

Latest commit

 

History

History
132 lines (89 loc) · 4.01 KB

CONTRIBUTING.md

File metadata and controls

132 lines (89 loc) · 4.01 KB

Contributing to Stanza

Development

You can view and edit the source code by cloning this repository:

git clone https://github.com/observiq/stanza.git

Pull Requests

How to Submit Pull Requests

Everyone is welcome to contribute code to stanza via GitHub pull requests (PRs).

To create a new PR, fork the project in GitHub and clone the upstream repo:

$ go get -d github.com/observiq/stanza

This will put the project in ${GOPATH}/src/github.com/observiq/stanza. You can alternatively use git directly with:

$ git clone https://github.com/observiq/stanza

This would put the project in the stanza directory in current working directory.

Enter the newly created directory and add your fork as a new remote:

$ git remote add <YOUR_FORK> [email protected]:<YOUR_GITHUB_USERNAME>/opentelemetry-go

Check out a new branch, make modifications, run linters and tests, and push the branch to your fork:

$ git checkout -b <YOUR_BRANCH_NAME>
# edit files
$ go test -race ./...
$ git add -p
$ git commit
$ git push <YOUR_FORK> <YOUR_BRANCH_NAME>

Open a pull request against the main stanza repo.

Commands to run before submitting PR

Our CI runs the following checks on each PR. You can run the following local commands to ensure your code is ready for PR:

  • Build (make build)
  • Test (make test)
  • Lint (make lint)

How to Receive Comments

  • If the PR is not ready for review, please put [WIP] in the title, tag it as work-in-progress, or mark it as draft.
  • If you're stuck, tag a maintainer and ask a question. We're here to help each other.
  • Make sure CI passes.

How to Get PRs Merged

A PR is considered to be ready to merge when:

  • It has received approval from at least two maintainers.
  • CI passes.
  • Major feedback is resolved.

Design Choices

Best practices for developing a builtin operator are documented below, but for changes to the core agent, we are happy to discuss proposals in the issue tracker.

Operator Development

In order to write an operator, follow these three steps:

  1. Build a unique struct that satisfies the Operator interface. This struct will define what your operator does when executed in the pipeline.
type ExampleOperator struct {
	FilePath string
}

func (p *ExampleOperator) Process(ctx context.Context, entry *entry.Entry) error {
	// Processing logic
}
  1. Build a unique config struct that satisfies the Config interface. This struct will define the parameters used to configure and build your operator struct in step 1.
type ExampleOperatorConfig struct {
	filePath string
}

func (c ExampleOperatorConfig) Build(context operator.BuildContext) (operator.Operator, error) {
	return &ExampleOperator{
		filePath: c.FilePath,
	}, nil
}
  1. 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.
func init() {
	operator.RegisterOperator("example_operator", &ExampleOperatorConfig{})
}

Any tips for building operators?

We highly recommend that developers take advantage of helpers 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.

For example, almost all operators should embed the BasicOperator helper, as it provides simple functionality for returning an operator id and operator type.

// ExampleOperator is a basic operator, with a basic lifecycle, that consumes
// but doesn't send log entries. Rather than implementing every part of the operator
// interface, we can embed the following helpers to achieve this effect.
type ExampleOperator struct {
	helper.BasicOperator
	helper.BasicLifecycle
	helper.BasicOutput
}