[Gelöst] Ich hab ein kleines Leistungsproblem.
Ich habe auch die 4.1.0er Version. Meine Datenbank ist aktuell 2.1 GB groß
Ich betreibe CCU-Historian und Grafana im Docker Container auf Synology.
Ich habe heute und gestern Datenpunkte der letzten 4 Jahre in die Datenbank gepumpt.
Ich hatte 1200 cux-dev logfiles, aus den vergangenen Jahren, die die CUxd auf Platte geschrieben hat.
Ich habe mir ein Script gebaut, welches diese Datenpunbkte alle in ccu-Historien bringt:
Seit dem, ist Grafana super langsam.
Kann ich Irgendwelche Logfiles, oder Werte bereit stellen, damit man mal prüfen kann, woran das liegt?
Auch das Update auf 4.1.0 hat nichts gebraucht.
Oder habe ich gar kein CCU-Historian, sondern ein Grafan Problem?
Er sagt mr plötzlich das die Maximale Reihen Anzahl erreuicht ist von 1 Million.
Ich verstehe gar nicht warum.
Das ist meine Suchabfrage
Code: Alles auswählen
SELECT
TIMESTAMPADD(HOUR, -1, "TS") AS "time",
"VALUE" AS "value"
FROM "D_BIDCOS_RF_LEQ0778901_4_ACTUAL_TEMPERATURE"
WHERE "TS" >= CURRENT_DATE - 365
ORDER BY "TS" ASC;
Ich bin ein Honk. Falsche Abfrage.
SO muss die richtige Grafana Abfrage lauten:
Code: Alles auswählen
SELECT
TIMESTAMPADD(HOUR, -1, "TS") AS "time",
"VALUE" AS "value"
FROM "D_BIDCOS_RF_LEQ0778901_4_ACTUAL_TEMPERATURE"
WHERE
"TS" BETWEEN $__timeFrom() AND $__timeTo()
ORDER BY "TS" ASC;
Speicherteschnisch, darf ccu-Historian bis zu 6 GB Ram allocieren (Der Container)
Bitte um Hilfe
Importscript
Code: Alles auswählen
// Stand: 15.03.25 12:47
// cux-dev.log.20241124-1654
// unter dem Ordner Database muss ein Ordner import angelegt werden
// dort schreibt das Script sein Logfile
// Dort erwartet das Skript die cux-dev Files (cux-dev muss im Namen vorhanden sein.). Nach erfolgreicher Bearbeitung werden die Dateien umbenannt in read.<Filename>
import java.nio.file.*
def logDirectory = new File("/database/import/")
if (!logDirectory.exists() || !logDirectory.isDirectory()) {
println "FEHLER: Importverzeichnis '/database/import/' nicht gefunden!"
return
}
// Initialisiere die Logdatei
def logFilePath = "/database/import/import_log.txt"
def logFile = new File(logFilePath)
def maxLogSize = 50 * 1024 * 1024 // 50 MB
// Variable für fehlerhafte Datenpunkte
def failedList = [] // 💡 Hier wird die fehlende Variable initialisiert!
// Logrotation prüfen
def rotateLogFile = {
if (logFile.exists() && logFile.length() > maxLogSize) {
int logIndex = 1
while (new File("/database/import/import_log_${logIndex}.txt").exists()) {
logIndex++
}
logFile.renameTo(new File("/database/import/import_log_${logIndex}.txt"))
logFile = new File(logFilePath) // Neue Logdatei erstellen
}
}
// Logging-Funktion mit Rotation
def writeLog = { message ->
rotateLogFile() // Vor dem Schreiben prüfen
def timestamp = new Date().format("yyyy-MM-dd HH:mm:ss")
def logMessage = "${timestamp} - ${message}\n"
try {
logFile.withWriterAppend { writer ->
writer.write(logMessage)
writer.flush()
}
} catch (Exception e) {
println "FEHLER beim Schreiben ins Log: ${e.message}"
}
}
// Methode für Konsolenausgabe + Logfile
def consolePrint = { message ->
println message
writeLog(message)
}
// Skript starten
consolePrint("Skript gestartet")
def logFiles = logDirectory.listFiles().findAll { file ->
file.isFile() && file.name.contains("cux-dev.log") && !file.name.startsWith("read.")
}
consolePrint("Anzahl gefundener Logdateien: ${logFiles.size()}")
logFiles.each { file -> consolePrint("Gefundene Datei: ${file.name}") }
if (logFiles.isEmpty()) {
consolePrint("WARNUNG: Keine neuen Logdateien zum Import gefunden.")
return
}
logFiles.sort { f1, f2 -> f1.name <=> f2.name }
int totalSuccess = 0
int totalFailed = 0
def tableMapping = [:]
def dataPoints = database.dataPoints
// **Datenpunkte mit verschiedenen Schreibweisen erfassen**
dataPoints.each { dp ->
try {
def key = "${dp.id.address}:${dp.id.identifier}"
def altKey1 = key.replaceAll(":", ".")
def altKey2 = key.replaceAll("\\.", ":")
def altKey3 = "${key}.VALUE"
def altKey4 = key.replaceAll("-", ".STATE")
def altKey5 = "${dp.displayName}.VALUE"
def altKey6 = dp.displayName
def tableName = dp.hasProperty("tableName") ? tableName.replaceAll("-", "_").replaceAll(":", "_").toUpperCase()
: "D_${dp.id.interfaceId}_${dp.id.address}_${dp.id.identifier}".toUpperCase()
// Alle Varianten speichern
tableMapping[key] = [dp.id.interfaceId, dp.id.address, dp.id.identifier, dp.displayName, tableName, dp]
[altKey1, altKey2, altKey3, altKey4, altKey5, altKey6].each { alt ->
tableMapping[alt] = tableMapping[key]
}
} catch (Exception e) {
writeLog("Fehler beim Abruf eines Datenpunkts: ${e.message}")
}
}
consolePrint("Bekannte Datenpunkte:")
tableMapping.each { k, v -> writeLog(" - ${k} -> ${v[3]} in Tabelle ${v[4]}") }
logFiles.each { File file ->
consolePrint("Starte Verarbeitung der Datei: ${file.name}")
def timeSeriesMap = [:]
int fileSuccess = 0
int fileFailed = 0
file.eachLine { line, lineNo ->
writeLog("Zeile ${lineNo} gelesen: '${line}'")
if (line?.trim()) {
try {
def parts = line.trim().split(/\s+/, 3)
writeLog("Zeile ${lineNo} nach Split: ${parts}")
if (parts.size() < 3) {
writeLog("FEHLER: Zeile ${lineNo} hat zu wenige Spalten!")
fileFailed++
return
}
def rawTimestamp = parts[0]
def idPart = parts[1]
def valueStr = parts[2]
String timeString = rawTimestamp.replace('T', ' ').split("\\.")[0]
Date timestamp = Date.parse("yyyy-MM-dd HH:mm:ss", timeString)
// **Alternative Schreibweisen für das Mapping**
def possibleKeys = [
idPart,
idPart.replaceAll(":", "."),
idPart.replaceAll("\\.", ":"),
"${idPart}.VALUE",
idPart.replaceAll("-", ".STATE"),
idPart.replaceAll("-", "_").toUpperCase()
]
def mappingEntry = possibleKeys.findResult { key -> tableMapping[key] }
if (!mappingEntry) {
fileFailed++
failedList << [idPart, rawTimestamp, valueStr]
writeLog("❌ FEHLER: Unbekannter Datenpunkt '${idPart}' (Zeile ${lineNo} in ${file.name}).")
writeLog("Geprüfte Alternativen: " + possibleKeys.join(", "))
return
}
def (iface, addr, param, displayName, tableName, dpObj) = mappingEntry
def cleanValueStr = valueStr.replace(",", ".")
Double value = Double.parseDouble(cleanValueStr)
int state = 3
if (!timeSeriesMap.containsKey(dpObj)) {
timeSeriesMap[dpObj] = new TimeSeries(dpObj)
}
timeSeriesMap[dpObj].add(new ProcessValue(timestamp, value, state))
fileSuccess++
writeLog("✅ ERFOLGREICH: Zeile ${lineNo} gespeichert - ${idPart}, Wert: ${value}, Tabelle: ${tableName}")
} catch (Exception ex) {
fileFailed++
failedList << [line, "-", "-"]
writeLog("❌ FEHLER: Problem in Zeile ${lineNo} von ${file.name}: ${ex.message}")
}
}
}
timeSeriesMap.each { dp, ts ->
if (ts.size() > 0) {
ts.sort { a, b -> a.timestamp <=> b.timestamp }
try {
database.insertTimeSeries(ts)
consolePrint("✅ Import abgeschlossen: ${ts.size()} Werte in '${dp.displayName}' gespeichert.")
} catch (Exception ex) {
fileFailed += ts.size()
writeLog("❌ FEHLER: Fehler beim Import in '${dp.displayName}': ${ex.message}")
}
}
}
totalSuccess += fileSuccess
totalFailed += fileFailed
def processedFile = new File(file.parentFile, "read.${file.name}")
if (file.renameTo(processedFile)) {
consolePrint("Datei erfolgreich umbenannt: ${file.name} -> ${processedFile.name}")
} else {
consolePrint("FEHLER: Datei konnte nicht umbenannt werden! (${file.name})")
}
consolePrint("📊 Datei '${file.name}' - Erfolgreich: ${fileSuccess}, Fehler: ${fileFailed}")
}
consolePrint("\n--------------------------------------------------")
consolePrint("✅ **IMPORT ABSCHLOSSEN**")
consolePrint("📄 Importlog: ${logFilePath}")
consolePrint("📂 Importverzeichnis: ${logDirectory}")
consolePrint("--------------------------------------------------")
consolePrint("✅ **Import abgeschlossen**. Gesamt erfolgreich: ${totalSuccess}, fehlerhafte Einträge: ${totalFailed}.")
Aktueller Stack:
Code: Alles auswählen
services:
ccu-historian:
image: docker.io/xjokay/ccu-historian:latest
container_name: ccu-historian
volumes:
- /volume1/docker/ccuhistorian/data/database:/database
- /volume1/docker/ccuhistorian/data/config:/opt/ccu-historian/config
ports:
- 84:80
- 2098:2098
- 2099:2099
- 8082:8082
environment:
- TZ=Europe/Berlin
- PUID=1027
- PGID=101
- CONFIG_CCU_TYPE=CCU3
- CONFIG_CCU_IP=192.168.99.xx
- CONFIG_HOST_IP=xxx.fritz.box
- CONFIG_HOST_BINRPCPORT=2099
- CONFIG_HOST_XMLRPCPORT=2098
- CONFIG_CCU_PLUGIN1_TYPE=CUXD
- CONFIG_KEEP_MONTHS=48
- CONFIG_MAINTENANC=true
# - CONFIG_JAVA_OPTS="-Xmx100m" # Allows to set Java custom settings, e.g. "-Xmx100m" to set the max heap size to 100 megabytes.
networks:
- monitoring
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
user: "1027:101"
volumes:
- /volume1/docker/grafana/data:/var/lib/grafana
- /volume1/docker/grafana/config:/etc/grafana
- /volume1/docker/grafana/log:/var/log/grafana
environment:
- TZ=Europe/Berlin
- GF_SECURITY_ADMIN_PASSWORD=xxx
- GF_USERS_ALLOW_SIGN_UP=false
- GF_LOG_LEVEL=debug
- GF_LOG_MODE=console, file
- GF_AUTH_DISABLE_LOGIN_FORM=false
- GF_AUTH_AUDIT_LOG=true
- GF_LOG_log_rotate=true
- GF_AUTH_DISABLE_BRUTEFORCE_PROTECTION=false
- GF_PATHS_CONFIG=/etc/grafana/grafana.ini
- GF_PATHS_DATA=/var/lib/grafana
- GF_PATHS_LOGS=/var/log/grafana
ports:
- 3000:3000
depends_on:
- ccu-historian
networks:
- monitoring
networks:
monitoring:
driver: bridge
Logauszug:
Code: Alles auswählen
at mdz.hc.itf.hm.HmXmlRpcClient.init(HmXmlRpcClient.groovy:55)
at mdz.hc.itf.hm.HmXmlRpcInterface.init(HmXmlRpcInterface.groovy:123)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.doCall(HmReinitTask.groovy:83)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.doCall(HmReinitTask.groovy:82)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.call(HmReinitTask.groovy)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.doCall(HmReinitTask.groovy:77)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask.checkInterfaces(HmReinitTask.groovy:73)
2025-03-15 19:29:49|SEVERE |Exception: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
2025-03-15 19:29:49|SEVERE |Detail: java.io.IOException: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
at mdz.hc.itf.hm.HmXmlRpcClient.init(HmXmlRpcClient.groovy:55)
at mdz.hc.itf.hm.HmXmlRpcInterface.init(HmXmlRpcInterface.groovy:123)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.doCall(HmReinitTask.groovy:83)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.doCall(HmReinitTask.groovy:82)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.call(HmReinitTask.groovy)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.doCall(HmReinitTask.groovy:77)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask.checkInterfaces(HmReinitTask.groovy:73)
2025-03-15 19:30:19|SEVERE |Exception: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
2025-03-15 19:30:19|SEVERE |Detail: java.io.IOException: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
at mdz.hc.itf.hm.HmXmlRpcClient.init(HmXmlRpcClient.groovy:55)
at mdz.hc.itf.hm.HmXmlRpcInterface.init(HmXmlRpcInterface.groovy:123)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.doCall(HmReinitTask.groovy:83)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.doCall(HmReinitTask.groovy:82)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.call(HmReinitTask.groovy)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.doCall(HmReinitTask.groovy:77)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask.checkInterfaces(HmReinitTask.groovy:73)
2025-03-15 19:30:49|SEVERE |Exception: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
2025-03-15 19:30:49|SEVERE |Detail: java.io.IOException: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
at mdz.hc.itf.hm.HmXmlRpcClient.init(HmXmlRpcClient.groovy:55)
at mdz.hc.itf.hm.HmXmlRpcInterface.init(HmXmlRpcInterface.groovy:123)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.doCall(HmReinitTask.groovy:83)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.doCall(HmReinitTask.groovy:82)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.call(HmReinitTask.groovy)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.doCall(HmReinitTask.groovy:77)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask.checkInterfaces(HmReinitTask.groovy:73)
2025-03-15 19:31:19|SEVERE |Exception: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
2025-03-15 19:31:19|SEVERE |Detail: java.io.IOException: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
at mdz.hc.itf.hm.HmXmlRpcClient.init(HmXmlRpcClient.groovy:55)
at mdz.hc.itf.hm.HmXmlRpcInterface.init(HmXmlRpcInterface.groovy:123)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.doCall(HmReinitTask.groovy:83)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.doCall(HmReinitTask.groovy:82)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.call(HmReinitTask.groovy)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.doCall(HmReinitTask.groovy:77)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask.checkInterfaces(HmReinitTask.groovy:73)
2025-03-15 19:31:49|SEVERE |Exception: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
2025-03-15 19:31:49|SEVERE |Detail: java.io.IOException: Server returned HTTP response code: 503 for URL: http://192.168.99.90:2000
at mdz.hc.itf.hm.HmXmlRpcClient.init(HmXmlRpcClient.groovy:55)
at mdz.hc.itf.hm.HmXmlRpcInterface.init(HmXmlRpcInterface.groovy:123)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.doCall(HmReinitTask.groovy:83)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3$_closure4.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.doCall(HmReinitTask.groovy:82)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1$_closure3.call(HmReinitTask.groovy)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.doCall(HmReinitTask.groovy:77)
at mdz.hc.itf.hm.HmReinitTask$_checkInterfaces_closure1.call(HmReinitTask.groovy)
at mdz.Exceptions.lambda$0(Exceptions.java:84)
at mdz.Exceptions.catchToLog(Exceptions.java:74)
at mdz.Exceptions.catchToLog(Exceptions.java:84)
at mdz.hc.itf.hm.HmReinitTask.checkInterfaces(HmReinitTask.groovy:73)
