Skip to content

Commit 0f7932f

Browse files
committed
sample project: add grafana
1 parent 9739b58 commit 0f7932f

File tree

10 files changed

+379
-21
lines changed

10 files changed

+379
-21
lines changed

kafka-questdb-connector-samples/stocks/docker-compose.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,31 @@ services:
1010
- QDB_CAIRO_COMMIT_LAG=1000
1111
- JAVA_OPTS=-Djava.locale.providers=JRE,SPI
1212
- QDB_LINE_DEFAULT_PARTITION_BY=YEAR
13+
- QDB_PG_SELECT_CACHE_ENABLED=false
1314
zookeeper:
1415
image: zookeeper:3.6.2
1516
ports:
1617
- "2181:2181"
18+
grafana:
19+
image: grafana/grafana-oss:9.2.1
20+
ports:
21+
- "3000:3000"
22+
volumes:
23+
- ./grafana/provisioning:/etc/grafana/provisioning/
24+
- ./grafana/dashboards/:/var/lib/grafana/dashboards/
25+
depends_on:
26+
- questdb
27+
links:
28+
- questdb:questdb
29+
environment:
30+
- GF_SECURITY_ADMIN_PASSWORD=quest
31+
- GF_SECURITY_ADMIN_USER=admin
32+
- GF_USERS_ALLOW_SIGN_UP=false
33+
- GF_USERS_ALLOW_ORG_CREATE=false
34+
- GF_AUTH_ANONYMOUS_ENABLED=true
35+
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
36+
- GF_AUTH_ANONYMOUS_ORG_NAME=Main Org.
37+
- GF_AUTH_ANONYMOUS_ORG_ID=1
1738
kafka:
1839
image: wurstmeister/kafka:2.13-2.8.1
1940
ports:
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
{
2+
"annotations": {
3+
"list": [
4+
{
5+
"builtIn": 1,
6+
"datasource": {
7+
"type": "grafana",
8+
"uid": "-- Grafana --"
9+
},
10+
"enable": true,
11+
"hide": true,
12+
"iconColor": "rgba(0, 211, 255, 1)",
13+
"name": "Annotations & Alerts",
14+
"target": {
15+
"limit": 100,
16+
"matchAny": false,
17+
"tags": [],
18+
"type": "dashboard"
19+
},
20+
"type": "dashboard"
21+
}
22+
]
23+
},
24+
"editable": true,
25+
"fiscalYearStartMonth": 0,
26+
"graphTooltip": 0,
27+
"id": 1,
28+
"links": [],
29+
"liveNow": false,
30+
"panels": [
31+
{
32+
"datasource": {
33+
"type": "postgres",
34+
"uid": "P2596F1C8E12435D2"
35+
},
36+
"fieldConfig": {
37+
"defaults": {
38+
"color": {
39+
"mode": "palette-classic"
40+
},
41+
"custom": {
42+
"axisCenteredZero": false,
43+
"axisColorMode": "text",
44+
"axisLabel": "",
45+
"axisPlacement": "auto",
46+
"barAlignment": 0,
47+
"drawStyle": "line",
48+
"fillOpacity": 0,
49+
"gradientMode": "none",
50+
"hideFrom": {
51+
"legend": false,
52+
"tooltip": false,
53+
"viz": false
54+
},
55+
"lineInterpolation": "linear",
56+
"lineWidth": 1,
57+
"pointSize": 5,
58+
"scaleDistribution": {
59+
"type": "linear"
60+
},
61+
"showPoints": "auto",
62+
"spanNulls": false,
63+
"stacking": {
64+
"group": "A",
65+
"mode": "none"
66+
},
67+
"thresholdsStyle": {
68+
"mode": "off"
69+
}
70+
},
71+
"mappings": [],
72+
"thresholds": {
73+
"mode": "absolute",
74+
"steps": [
75+
{
76+
"color": "green",
77+
"value": null
78+
},
79+
{
80+
"color": "red",
81+
"value": 80
82+
}
83+
]
84+
}
85+
},
86+
"overrides": []
87+
},
88+
"gridPos": {
89+
"h": 11,
90+
"w": 14,
91+
"x": 0,
92+
"y": 0
93+
},
94+
"id": 2,
95+
"options": {
96+
"candleStyle": "candles",
97+
"colorStrategy": "open-close",
98+
"colors": {
99+
"down": "red",
100+
"up": "green"
101+
},
102+
"includeAllFields": false,
103+
"legend": {
104+
"calcs": [],
105+
"displayMode": "list",
106+
"placement": "bottom",
107+
"showLegend": true
108+
},
109+
"mode": "candles+volume"
110+
},
111+
"targets": [
112+
{
113+
"datasource": {
114+
"type": "postgres",
115+
"uid": "P2596F1C8E12435D2"
116+
},
117+
"format": "time_series",
118+
"group": [],
119+
"metricColumn": "none",
120+
"rawQuery": true,
121+
"rawSql": "SELECT\n $__time(timestamp),\n min(price) as low,\n max(price) as high,\n first(price) as open,\n last(price) as close\nFROM\n stock\nWHERE\n $__timeFilter(timestamp)\n and symbol = '$Symbol'\nSAMPLE BY $Interval ALIGN TO CALENDAR;",
122+
"refId": "A",
123+
"select": [
124+
[
125+
{
126+
"params": [
127+
"value"
128+
],
129+
"type": "column"
130+
}
131+
]
132+
],
133+
"timeColumn": "time",
134+
"where": [
135+
{
136+
"name": "$__timeFilter",
137+
"params": [],
138+
"type": "macro"
139+
}
140+
]
141+
}
142+
],
143+
"title": "Stocks",
144+
"type": "candlestick"
145+
}
146+
],
147+
"refresh": "5s",
148+
"schemaVersion": 37,
149+
"style": "dark",
150+
"tags": [],
151+
"templating": {
152+
"list": [
153+
{
154+
"current": {
155+
"selected": false,
156+
"text": "IBM",
157+
"value": "IBM"
158+
},
159+
"datasource": {
160+
"type": "postgres",
161+
"uid": "P2596F1C8E12435D2"
162+
},
163+
"definition": "select distinct symbol from 'stock';",
164+
"hide": 0,
165+
"includeAll": false,
166+
"multi": false,
167+
"name": "Symbol",
168+
"options": [],
169+
"query": "select distinct symbol from 'stock';",
170+
"refresh": 1,
171+
"regex": "",
172+
"skipUrlSync": false,
173+
"sort": 0,
174+
"type": "query"
175+
},
176+
{
177+
"auto": true,
178+
"auto_count": 30,
179+
"auto_min": "1s",
180+
"current": {
181+
"selected": false,
182+
"text": "1s",
183+
"value": "1s"
184+
},
185+
"hide": 0,
186+
"name": "Interval",
187+
"options": [
188+
{
189+
"selected": false,
190+
"text": "auto",
191+
"value": "$__auto_interval_Interval"
192+
},
193+
{
194+
"selected": true,
195+
"text": "1s",
196+
"value": "1s"
197+
},
198+
{
199+
"selected": false,
200+
"text": "5s",
201+
"value": "5s"
202+
},
203+
{
204+
"selected": false,
205+
"text": "30s",
206+
"value": "30s"
207+
},
208+
{
209+
"selected": false,
210+
"text": "1m",
211+
"value": "1m"
212+
},
213+
{
214+
"selected": false,
215+
"text": "2m",
216+
"value": "2m"
217+
},
218+
{
219+
"selected": false,
220+
"text": "5m",
221+
"value": "5m"
222+
},
223+
{
224+
"selected": false,
225+
"text": "10m",
226+
"value": "10m"
227+
}
228+
],
229+
"query": "1s,5s,30s,1m,2m,5m,10m",
230+
"queryValue": "",
231+
"refresh": 2,
232+
"skipUrlSync": false,
233+
"type": "interval"
234+
}
235+
]
236+
},
237+
"time": {
238+
"from": "now-5m",
239+
"to": "now"
240+
},
241+
"timepicker": {},
242+
"timezone": "",
243+
"title": "Stocks",
244+
"uid": "stocks",
245+
"version": 1,
246+
"weekStart": ""
247+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: 1
2+
3+
providers:
4+
# <string> an unique provider name. Required
5+
- name: 'a stock dashboard provider'
6+
# <int> Org id. Default to 1
7+
orgId: 1
8+
# <string> name of the dashboard folder.
9+
folder: ''
10+
# <string> folder UID. will be automatically generated if not specified
11+
folderUid: ''
12+
# <string> provider type. Default to 'file'
13+
type: file
14+
# <bool> disable dashboard deletion
15+
disableDeletion: false
16+
# <int> how often Grafana will scan for changed dashboards
17+
updateIntervalSeconds: 10
18+
# <bool> allow updating provisioned dashboards from the UI
19+
allowUiUpdates: true
20+
options:
21+
# <string, required> path to dashboard files on disk. Required when using the 'file' type
22+
path: /var/lib/grafana/dashboards
23+
# <bool> use folder names from filesystem to create folders in Grafana
24+
foldersFromFilesStructure: true
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: 1
2+
3+
datasources:
4+
- name: QuestDB
5+
type: postgres
6+
url: questdb:8812
7+
database: qdb
8+
user: admin
9+
secureJsonData:
10+
password: "quest"
11+
jsonData:
12+
sslmode: "disable" # disable/require/verify-ca/verify-full
13+
maxOpenConns: 0 # Grafana v5.4+
14+
maxIdleConns: 2 # Grafana v5.4+
15+
connMaxLifetime: 14400 # Grafana v5.4+
16+
postgresVersion: 903 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10
17+
timescaledb: false

kafka-questdb-connector-samples/stocks/readme.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ curl -X POST -H "Content-Type: application/json" -d '{"name":"debezium_source",
55

66
Kafka -> QuestDB
77
```shell
8-
curl -X POST -H "Content-Type: application/json" -d '{"name":"questdb-connect","config":{"topics":"dbserver1.public.stock","table":"stock", "connector.class":"io.questdb.kafka.QuestDBSinkConnector","tasks.max":"1","key.converter":"org.apache.kafka.connect.storage.StringConverter","value.converter":"org.apache.kafka.connect.json.JsonConverter","host":"questdb", "transforms":"unwrap", "transforms.unwrap.type":"io.debezium.transforms.ExtractNewRecordState", "transforms.unwrap.add.fields": "source.ts_ms", "include.key": "false", "symbols": "symbol", "timestamp.field.name": "__source_ts_ms"}}' localhost:8083/connectors
9-
```
8+
curl -X POST -H "Content-Type: application/json" -d '{"name":"questdb-connect","config":{"topics":"dbserver1.public.stock","table":"stock", "connector.class":"io.questdb.kafka.QuestDBSinkConnector","tasks.max":"1","key.converter":"org.apache.kafka.connect.storage.StringConverter","value.converter":"org.apache.kafka.connect.json.JsonConverter","host":"questdb", "transforms":"unwrap", "transforms.unwrap.type":"io.debezium.transforms.ExtractNewRecordState", "include.key": "false", "symbols": "symbol", "timestamp.field.name": "last_update"}}' localhost:8083/connectors
9+
```
10+
11+
[Grafana Dashboard](http://localhost:3000/d/stocks/stocks?orgId=1&refresh=5s&viewPanel=2)

kafka-questdb-connector-samples/stocks/src/main/java/io/questdb/kafka/samples/Stock.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import org.springframework.data.annotation.Id;
44

5+
import java.sql.Timestamp;
6+
57
public class Stock {
68
private @Id Long id;
79
private String symbol;
810
private double price;
11+
private Timestamp last_update;
912

1013
public String getSymbol() {
1114
return symbol;
@@ -31,12 +34,21 @@ public void setId(long id) {
3134
this.id = id;
3235
}
3336

37+
public Timestamp getTimestamp() {
38+
return last_update;
39+
}
40+
41+
public void setTimestamp(Timestamp timestamp) {
42+
this.last_update = timestamp;
43+
}
44+
3445
@Override
3546
public String toString() {
3647
return "Stock{" +
3748
"id=" + id +
3849
", symbol='" + symbol + '\'' +
3950
", price=" + price +
51+
", last_update=" + last_update +
4052
'}';
4153
}
4254
}

kafka-questdb-connector-samples/stocks/src/main/java/io/questdb/kafka/samples/StockRepository.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
import org.springframework.data.repository.query.Param;
1212
import org.springframework.stereotype.Repository;
1313

14+
import java.sql.Timestamp;
1415
import java.util.List;
1516

1617
@Repository
1718
public interface StockRepository extends CrudRepository<Stock, String> {
1819

1920
@Modifying
20-
@Query("UPDATE stock SET price = price * :factor WHERE symbol = :symbol")
21-
boolean updateBySymbol(@Param("symbol") String symbol, @Param("factor") double factor);
21+
@Query("UPDATE stock SET price = price + :delta, last_update = :timestamp WHERE symbol = :symbol")
22+
boolean updateBySymbol(@Param("symbol") String symbol, @Param("delta") double delta, @Param("timestamp") Timestamp timestamp);
2223

2324
@Query("SELECT symbol FROM stock")
2425
List<String> findAllSymbols();

0 commit comments

Comments
 (0)