You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a Logstash output plugin (`logstash-output-kusto`) that sends events from Logstash to Azure Data Explorer (Kusto). It is a JRuby gem that wraps the Azure Kusto Java SDK. The plugin runs on the JVM via Logstash's embedded JRuby runtime.
6
+
7
+
## Architecture
8
+
9
+
The plugin has three core classes, all nested under `LogStash::Outputs::Kusto`:
10
+
11
+
-**`Kusto` (kusto.rb)** — Main output plugin. Extends `LogStash::Outputs::Base`. Handles Logstash config registration, file I/O (writing events to temp files with time-based rotation), and lifecycle (`register`, `multi_receive_encoded`, `close`). Uses `concurrency :shared`.
12
+
-**`Ingestor` (kusto/ingestor.rb)** — Manages authentication (AAD app credentials, managed identity, or CLI auth) and async upload to Kusto via the Java SDK. Runs uploads on a `Concurrent::ThreadPoolExecutor`. Retries indefinitely on transient upload failures.
13
+
-**`Interval` (kusto/interval.rb)** — Simple timer utility that runs a callable at a fixed interval using a background thread with `Mutex`/`ConditionVariable`.
14
+
-**`IOWriter`** — Wrapper around file descriptors at the bottom of `kusto.rb`, tracking active/inactive state for stale file cleanup.
15
+
16
+
Data flow: Events → codec encodes to JSON lines → written to time-rotated temp files → stale files closed → `Ingestor.upload_async` queues file for Kusto ingestion via Java SDK → temp file deleted on success.
17
+
18
+
## Build System
19
+
20
+
This project uses a dual build system — Gradle for Java dependency management and Bundler/Gem for JRuby packaging.
21
+
22
+
**Vendor Java dependencies (required before tests or gem build):**
23
+
```sh
24
+
./gradlew vendor
25
+
```
26
+
This resolves the Kusto Java SDK and all transitive dependencies, copies JARs to `vendor/jar-dependencies/`, and generates `lib/logstash-output-kusto_jars.rb`.
The script runs the full pipeline: install bundler → bundle install → vendor JARs → run unit tests → build gem → install the gem into local Logstash → run e2e tests. E2e tests also require Kusto cluster connection variables (`ENGINE_URL`, `INGEST_URL`, `TEST_DATABASE`) and use Azure CLI auth.
71
+
72
+
## Linting
73
+
74
+
RuboCop is configured (`.rubocop.yml`) with max line length of 120 characters.
75
+
76
+
## Key Conventions
77
+
78
+
-**JRuby required** — All Ruby commands must use `jruby -S` (not `ruby`). The gem platform is `java` and the code uses Java interop extensively.
79
+
-**Version source of truth** — The gem version is read from the `version` file in the project root (not hardcoded in the gemspec).
80
+
-**Java interop pattern** — Java classes are accessed via `Java::com.microsoft.azure.kusto.*` namespace. The `_jars.rb` file is auto-generated by Gradle — never edit it manually.
81
+
-**Logstash plugin conventions** — Config parameters use `config :name, validate: :type, default: value`. The plugin uses `config_name 'kusto'` and `default :codec, 'json_lines'`.
-**Dynamic field references** — Logstash `%{field}` references are allowed in `path` (for time-based file rotation) but explicitly forbidden in `database`, `table`, and `json_mapping`.
84
+
-**Test style** — RSpec with `logstash-devutils`. Tests mock the logger with `spy('logger')`. The `spec_helpers.rb` captures stdout/stderr in an `around` filter and sets log level to debug.
0 commit comments