Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage Extension 1/N #2883

Merged
merged 12 commits into from
Apr 2, 2021
Merged

Storage Extension 1/N #2883

merged 12 commits into from
Apr 2, 2021

Conversation

djaglowski
Copy link
Member

@djaglowski djaglowski commented Mar 25, 2021

First step towards implementing plan laid out in #2287 (direct link to design doc)

  • Adds a storage package
    • Defines a storage.Extension interface that extends component.Extension
    • Defines a storage.Client interface that requires Get, Set, Delete methods
    • Defines a concrete NopClient which can be used when no storage extension is enabled
  • Adds a local_file_storage extension which implements storage.Extension (functionality not yet implemented)

TODO

  • Incorporate feedback on initial implementation
  • Finish concrete implementation of local_file_storage
  • Tests
  • Documentation

@codecov
Copy link

codecov bot commented Mar 25, 2021

Codecov Report

Merging #2883 (06f524f) into main (a835321) will increase coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #2883   +/-   ##
=======================================
  Coverage   91.55%   91.55%           
=======================================
  Files         464      464           
  Lines       22860    22860           
=======================================
+ Hits        20929    20930    +1     
+ Misses       1438     1437    -1     
  Partials      493      493           
Flag Coverage Δ
integration 68.96% <ø> (-0.07%) ⬇️
unit 90.52% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
receiver/carbonreceiver/transport/tcp_server.go 67.00% <0.00%> (+1.00%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a835321...06f524f. Read the comment docs.

@djaglowski djaglowski marked this pull request as ready for review March 26, 2021 13:53
@djaglowski djaglowski requested a review from a team March 26, 2021 13:53
@jpkrohling
Copy link
Member

Is this only for logs?

@djaglowski
Copy link
Member Author

@jpkrohling It's intended to be for all signals/components.

Copy link
Member

@tigrannajaryan tigrannajaryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just doc comments.

extension/storage/README.md Outdated Show resolved Hide resolved
extension/storage/README.md Outdated Show resolved Hide resolved
@jrcamp
Copy link
Contributor

jrcamp commented Apr 1, 2021

You'll want to run make gendependabot at some point (broken right now due to #2956).

extension/storage/storage.go Outdated Show resolved Hide resolved
extension/storage/storage.go Outdated Show resolved Hide resolved

package storage

type NopClient struct{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the model we have in core. and provide a func NewNopClient() Client and avoid exposing the new struct.

May also want to have this in a storagetest package, can be done later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this to follow the pattern established in core. However, I have a question about potentially keeping NewNopClient available.

One of the expectations is that components that make use of a storage extension should seamlessly handle the situation where no storage extension is configured. My intention with introducing this nopClient was to provide an easy way for components to fulfill this expectation. Consider:

// Start the component
func (c *myComponent) Start(ctx context.Context, host component.Host) error {
    client := getStorageClient(ctx, host)
    
    // component implementation uses client but doesn't care if it's nop or not
}


func getStorageClient(ctx context.Context, host component.Host) storage.Client {
    for _, ext := range host.GetExtensions() {
        if ext is a storage extension {
            return ext.GetClient()
        }
    }
    return storage.NewNopClient()
}

Do you think this is a useful pattern? I suppose components can implement their own nopClient if necessary, but I thought it might be helpful to include.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see in practice how this will be used in few examples, probably we should make sure we re-evaluate this after couple of PRs that uses it.

extension/storage/storage.go Outdated Show resolved Hide resolved
@bogdandrutu bogdandrutu merged commit e335d83 into main Apr 2, 2021
@bogdandrutu bogdandrutu deleted the storage-extension-1 branch April 2, 2021 22:07
tigrannajaryan pushed a commit that referenced this pull request Apr 16, 2021
Follows #2883 

Will resolve #2287

### Summary

This PR includes:
- A full implementation of a `file_storage` extension, which can read and write data to the local file system. Any component in the collector may make use of this extension.
- Updates to `stanza/internal` to allow stanza-based receivers to use the extension for checkpoints.
- A new testbed scenario that has the filelogreceiver using the extension

Configuration of the extension is simple. 
```yaml
  file_storage:
  file_storage/all_settings:
    directory: /var/lib/otelcol/mydir
    timeout: 2s
```

The extension is made available to component's via the `host` parameter in their `Start` method:
```go
func (r *receiver) Start(ctx context.Context, host component.Host) error {
	for _, ext := range host.GetExtensions() {
		if se, ok := ext.(storage.Extension); ok {
			client, err := se.GetClient(ctx, component.KindReceiver, r.NamedEntity)
			if err != nil {
				return err
			}
			r.storageClient = client
			return nil
		}
	}
	r.storageClient = storage.NewNopClient()
        ...
}
```
pmatyjasek-sumo pushed a commit to pmatyjasek-sumo/opentelemetry-collector-contrib that referenced this pull request Apr 28, 2021
* WIP - Add storage extension framework

* Cleaned up initial implmenetation. Still much to do

* Remove extraneous dependency

* go tidy

* rm gopls from go.mod

* Fix typo in TODO

* Finish thought in readme

* Document storage.Extension, fix doc issues

* Run make gendependabot and make gotidy

* Use core nop pattern, add context to methods, clean up comments
pmatyjasek-sumo added a commit to pmatyjasek-sumo/opentelemetry-collector-contrib that referenced this pull request Apr 28, 2021
Follows open-telemetry#2883

Will resolve #2287

### Summary

This PR includes:
- A full implementation of a `file_storage` extension, which can read and write data to the local file system. Any component in the collector may make use of this extension.
- Updates to `stanza/internal` to allow stanza-based receivers to use the extension for checkpoints.
- A new testbed scenario that has the filelogreceiver using the extension

Configuration of the extension is simple.
```yaml
  file_storage:
  file_storage/all_settings:
    directory: /var/lib/otelcol/mydir
    timeout: 2s
```

The extension is made available to component's via the `host` parameter in their `Start` method:
```go
func (r *receiver) Start(ctx context.Context, host component.Host) error {
	for _, ext := range host.GetExtensions() {
		if se, ok := ext.(storage.Extension); ok {
			client, err := se.GetClient(ctx, component.KindReceiver, r.NamedEntity)
			if err != nil {
				return err
			}
			r.storageClient = client
			return nil
		}
	}
	r.storageClient = storage.NewNopClient()
        ...
}
```
# Conflicts:
#	go.mod
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants