-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
10 changed files
with
231 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,16 @@ | ||
# `Elastic.Ingest` | ||
# `Elastic.Ingest.*` | ||
|
||
This repository houses various `Elastic.Ingest.*` packages that utilize `Elastic.Channels` to send bulk data to various (Elastic) endpoints. | ||
|
||
## Usage | ||
|
||
### Projects | ||
|
||
```c# | ||
``` | ||
* [Elastic.Channels](src/Elastic.Channels/README.md) - core library that implements a batching `System.Threading.Channels.ChannelWriter` | ||
* [Elastic.Ingest.Transport](src/Elastic.Ingest.Transport/README.md) - core library that ships common setup for pushing data utilizing [Elastic.Transport](https://github.com/elastic/elastic-transport-net) | ||
* [Elastic.Ingest.Elasticsearch](src/Elastic.Ingest.Elasticsearch/README.md) - exposes `DataStreamChannel` and `IndexChannel` to push data to Elasticsearch with great ease. | ||
|
||
#### in development | ||
* [Elastic.Ingest.APM](src/Elastic.Ingest.Apm/README.md) - Pushes APM data to apm-server over the V2 intake API. Still under development. | ||
|
||
### Projects | ||
#### No plans of releasing | ||
* [Elastic.Ingest.OpenTelemetry](src/Elastic.Ingest.OpenTelemetry/README.md) - a toy implementation of `Elastic.Channels` that pushes `Activities` over `OTLP` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Elastic.Channels | ||
|
||
Provides an specialized `System.Threading.Channels.ChannelWriter` implementation that makes it easy | ||
to consume data pushed to that thread in batches. | ||
|
||
The batches will emit either when a certain maximum is hit or when a batch's lifecycle exceeds a certain age. | ||
|
||
This allows data of various rates to pushed in the same manner while different implementations to send the batched data to receivers can be implemented. | ||
|
||
This package serves mainly as a core library with abstract classes | ||
and does not ship any useful implementations. | ||
|
||
It ships with a `NoopBufferedChannel` implementation that does nothing in its `Send` implementation for unit test and benchmark purposes. | ||
|
||
|
||
## BufferedChannelBase<> | ||
|
||
An abstract class that requires implementers to implement: | ||
|
||
```csharp | ||
protected abstract Task<TResponse> Send(IReadOnlyCollection<TEvent> buffer); | ||
``` | ||
|
||
Any implementation allows data to pushed to it through: | ||
|
||
```csharp | ||
var e = new TEvent(); | ||
if (await channel.WaitToWriteAsync(e)) | ||
written++; | ||
``` | ||
|
||
## ChannelOptionsBase<> | ||
|
||
Implementers of `BufferedChannelBase<>` must also create their own implementation of `ChannelOptionsBase<>`. This to ensure each channel implementation creates an appropriately named options class. | ||
|
||
|
||
## Quick minimal implementation | ||
|
||
```chsarp | ||
public class Event { } | ||
public class Response { } | ||
public class NoopChannelOptions | ||
: ChannelOptionsBase<Event, Response> { } | ||
public class NoopBufferedChannel | ||
: BufferedChannelBase<NoopChannelOptions, Event, Response> | ||
{ | ||
public NoopBufferedChannel(NoopChannelOptions options) | ||
: base(options) { } | ||
protected override Task<Response> Send(IReadOnlyCollection<NoopEvent> buffer) | ||
{ | ||
return Task.FromResult(new Response()); | ||
} | ||
} | ||
``` | ||
|
||
Now once we instantiate an `NoopBufferedChannel` we can use it push data to it. | ||
|
||
```csharp | ||
var e = new Event(); | ||
if (await noopChannel.WaitToWriteAsync(e)) | ||
written++; | ||
``` | ||
|
||
|
||
## BufferOptions | ||
|
||
Each `ChannelOptionsBase<>` implementation takes and exposes a `BufferOptions` instance. This controls the buffering behavior of `BufferedChannelBase<>`. | ||
|
||
|
||
| Option | Description | | ||
|-----------------------------|------------------------------------------------------------------------------------------------------------------------------| | ||
| `MaxInFlightMessages` | The maximum number of in flight instances that can be queued in memory. If this threshold is reached, events will be dropped | | ||
| `MaxConsumerBufferSize` | The number of events a local buffer should reach before sending the events in a single call to Elasticsearch. | | ||
| `MaxRetries` | The maximum number of retries over `Send` | | ||
| `MaxConsumerBufferLifetime` | The maximum age of buffer before its flushed | | ||
| `ConcurrentConsumers` | Controls how many concurrent `Send` operations may occur | | ||
| `BackOfPeriod` | Func that calculates an appropriate backoff time for a retry | | ||
| `BufferFlushCallback` | Called `once` whenever a buffer is flushed, excluding retries | | ||
| `WaitHandle` | Inject a waithandle that will be signalled after each flush, excluding retries. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Elastic.Ingest.APM | ||
|
||
A `Elastic.Channel` implementation of `BufferedChannelBase` that allows APM data to be written to `apm-server` over the V2 intake API. | ||
|
||
|
||
Utilizes `Elastic.Transport` through `Elastic.Ingest.Transport`. | ||
|
||
|
||
This project is currently still under development and not pushed to Nuget. | ||
|
||
We are still working on finishing this implementation as a possible replacement for the PayloadSender that's currently part of `Elastic.Apm` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Elastic.Ingest.Elasticsearch | ||
|
||
`Elastic.Channels` implementations of `BufferedChannelBase` that allows data to pushed to either indices or data streams | ||
|
||
|
||
## `DataStreamChannel<TEvent>` | ||
|
||
A channel that specializes to writing data with a timestamp to Elasticsearch data streams. E.g given the following document. | ||
|
||
```csharp | ||
public class TimeSeriesDocument | ||
{ | ||
[JsonPropertyName("@timestamp")] | ||
public DateTimeOffset Timestamp { get; set; } | ||
|
||
[JsonPropertyName("message")] | ||
public string Message { get; set; } | ||
} | ||
|
||
``` | ||
|
||
A channel can be created to push data to the `logs-dotnet-default` data stream. | ||
|
||
```csharp | ||
var dataStream = new DataStreamName("logs", "dotnet"); | ||
var bufferOptions = new BufferOptions { } | ||
var options = new DataStreamChannelOptions<TimeSeriesDocument>(transport) | ||
{ | ||
DataStream = dataStream, | ||
BufferOptions = bufferOptions | ||
}; | ||
var channel = new DataStreamChannel<TimeSeriesDocument>(options); | ||
``` | ||
|
||
NOTE: read more about Elastic's data stream naming convention here: | ||
https://www.elastic.co/blog/an-introduction-to-the-elastic-data-stream-naming-scheme | ||
|
||
we can now push data to Elasticsearch using the `DataStreamChannel` | ||
```csharp | ||
var doc = new TimeSeriesDocument | ||
{ | ||
Timestamp = DateTimeOffset.Now, | ||
Message = "Hello World!", | ||
} | ||
channel.TryWrite(doc); | ||
``` | ||
|
||
# `IndexChannel<TEvent>` | ||
|
||
A channel that specializes in writing catalog data to Elastic indices. | ||
Catalog data is typically data that has an id of sorts. | ||
|
||
Given the following minimal document | ||
|
||
```csharp | ||
public class CatalogDocument | ||
{ | ||
[JsonPropertyName("id")] | ||
public string Id { get; set; } | ||
|
||
[JsonPropertyName("title")] | ||
public string Title { get; set; } | ||
|
||
[JsonPropertyName("created")] | ||
public DateTimeOffset Created { get; set; } | ||
} | ||
``` | ||
|
||
We can create an `IndexChannel<>` to push `CatalogDocument` instances. | ||
|
||
```csharp | ||
var options = new IndexChannelOptions<CatalogDocument>(transport) | ||
{ | ||
IndexFormat = "catalog-data-{0:yyyy.MM.dd}", | ||
BulkOperationIdLookup = c => c.Id, | ||
TimestampLookup = c => c.Created, | ||
}; | ||
var channel = new IndexChannel<CatalogDocument>(options); | ||
``` | ||
|
||
now we can push data using: | ||
|
||
```csharp | ||
var doc = new CatalogDocument | ||
{ | ||
Created = date, | ||
Title = "Hello World!", | ||
Id = "hello-world" | ||
} | ||
channel.TryWrite(doc); | ||
``` | ||
|
||
This will push data to `catalog-data-2023.01.1` because `TimestampLookup` yields `Created` to `IndexFormat`. | ||
|
||
`IndexFormat` can also simply be a fixed string to write to an Elasticsearch alias/index. | ||
|
||
`BulkOperationIdLookup` determines if the document should be pushed to Elasticsearch using a `create` or `index` operation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Elastic.Ingest.OpenTelemetry | ||
|
||
A `Elastic.Channel` implementation of `BufferedChannelBase` that allows OpenTelemetry data to be written over OTLP. | ||
|
||
This is not currently published to NuGet with no current plans to ever do so. | ||
|
||
This project currently only exists as a proof of concept to validate the concepts of `Elastic.Channels` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Elastic.Ingest.Transport | ||
|
||
An abstract `Elastic.Channels` implementation of `BufferedChannelBase` that allows implementes to quickly utilize `Elastic.Transport` to send data over HTTP(S) to one or many receiving endpoints. | ||
|
||
This is a core library that does not ship any useful implementation. | ||
|
||
See e.g `Elastic.Ingest.Elasticsearch` for a concrete implementation to push data to Elasticsearch |