From 6fecc0c641604936e46dc5288ca91ec6954542c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C5=A0ari=C4=87?= Date: Sat, 1 Nov 2025 15:09:43 +0100 Subject: [PATCH] Add README and upgrade Java version to 21 - Added comprehensive `README.md` with setup, usage instructions, and troubleshooting. - Updated Java toolchain to require Java 21 (from Java 17). --- .idea/misc.xml | 2 +- README.md | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ build.gradle | 2 +- 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 README.md diff --git a/.idea/misc.xml b/.idea/misc.xml index 7ce6a9b..32d884a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..09983b7 --- /dev/null +++ b/README.md @@ -0,0 +1,106 @@ +# DashboardSummary + +A small Java service that periodically queries InfluxDB metrics, asks Google Gemini to produce a short human‑friendly summary (2–4 sentences), and writes that summary back to InfluxDB for display on dashboards. + +## Features +- Pulls metrics from InfluxDB with configurable measurement/field filters +- Aggregates over a fixed time window (mean/min/max/last) +- Sends a compact JSON payload to Gemini with optional system instruction +- Writes the generated summary to an output measurement in the same bucket +- Can run once (batch mode) or on a fixed schedule + +## Requirements +- Java 21+ (the Docker image uses Temurin 21 JRE but the app targets 17) +- InfluxDB 2.x with an API token and bucket/org +- Google Generative Language (Gemini) API key +- Gradle (wrapper included) + +Configuration (Environment Variables) +The application reads configuration from environment variables at startup. + +### Required +- `INFLUX_URL`: URL of InfluxDB (e.g., http://localhost:8086) +- `INFLUX_TOKEN`: InfluxDB API token with read/write access to the bucket +- `INFLUX_ORG`: InfluxDB organization name/ID +- `INFLUX_BUCKET`: InfluxDB bucket name +- `GOOGLE_API_KEY`: Google Gemini API key + +### Optional (with defaults) +- `INFLUX_MEASUREMENT_REGEX`: Regex for measurements to include (default: .*) +- `INFLUX_FIELD_REGEX`: Regex for fields to include (default: unset = all fields) +- `GOOGLE_MODEL`: Gemini model (default: gemini-2.5-flash) +- `OUTPUT_MEASUREMENT`: Measurement to write summaries to (default: dashboard_summary) +- `INTERVAL_MINUTES`: Window size and schedule period in minutes (default: 15) +- `TIMEZONE`: IANA timezone for scheduling (default: system timezone) +- `RUN_ONCE`: If true, runs a single cycle and exits (default: false) +- `SYSTEM_INSTRUCTION`: System prompt sent to Gemini (default: "You are a concise observability assistant.") + +## Quick start (local) +### 1) Export environment variables (example) + + + export INFLUX_URL="http://localhost:8086" + export INFLUX_TOKEN="" + export INFLUX_ORG="" + export INFLUX_BUCKET="" + export GOOGLE_API_KEY="" + +#### Optional filters and settings + + export INFLUX_MEASUREMENT_REGEX="^telemetry_.*$" + export INFLUX_FIELD_REGEX="^(temperature|humidity)$" + export INTERVAL_MINUTES=15 + export RUN_ONCE=false + +### 2) Build and run with Gradle + ./gradlew run + + To build a distribution you can run: + + ./gradlew installDist + ./build/install/DashboardSummary/bin/DashboardSummary + +## Run once (batch mode) +Set `RUN_ONCE=true` to execute a single summary cycle and exit. + + RUN_ONCE=true ./gradlew run + # or with the installed distribution + RUN_ONCE=true ./build/install/DashboardSummary/bin/DashboardSummary + +## Docker +Build the image (multi-stage Dockerfile provided): + + docker build -t dashboard-summary:latest . + +Run the container (pass env variables): + + docker run --rm \ + -e INFLUX_URL=http://influxdb:8086 \ + -e INFLUX_TOKEN=YOUR_TOKEN \ + -e INFLUX_ORG=YOUR_ORG \ + -e INFLUX_BUCKET=YOUR_BUCKET \ + -e GOOGLE_API_KEY=YOUR_GEMINI_KEY \ + -e INFLUX_MEASUREMENT_REGEX=".*" \ + -e INTERVAL_MINUTES=15 \ + -e OUTPUT_MEASUREMENT=dashboard_summary \ + --name dashboard-summary dashboard-summary:latest + +## How it works +- For the last `INTERVAL_MINUTES`, the app queries InfluxDB for each matching measurement/field and computes mean, min, max, and last values. +- It composes a compact JSON payload with these stats and asks Gemini to write a short summary. +- The summary is written back to InfluxDB in `OUTPUT_MEASUREMENT` with fields: text (string) and interval_minutes (int), and tag: model. + +## Notes and tips +- Ensure the Influx token has read permission for source measurement(s) and write permission for `OUTPUT_MEASUREMENT` in the target bucket. +- `TIMEZONE` only affects when periodic runs are scheduled; the data range is relative to "now" per InfluxDB. +- If you need stricter control over prompting, set `SYSTEM_INSTRUCTION` to guide the model’s tone and focus. + +## Troubleshooting +- Missing configuration: the app logs a clear list of missing variables and exits with code 1. +- Gemini API errors: you will see the HTTP status and body in logs; verify `GOOGLE_API_KEY` and model. +- Influx query failures: the app logs a warning per failed query and continues with available data. + +## Development +- Build and test: ./gradlew build +- Code entry point: com.pathvariable.smartgarden.summary.Main +- Key classes: Config, GeminiClient, SummaryJob, TimeUtil, MetricKey diff --git a/build.gradle b/build.gradle index 1da9c16..ce457b3 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ version = '1.0-SNAPSHOT' java { toolchain { - languageVersion = JavaLanguageVersion.of(17) + languageVersion = JavaLanguageVersion.of(21) } }