2. Docker Compose Files
services:
elasticsearch:
image: docker.io/elastic/elasticsearch:7.10.2
container_name: elasticsearch_7.10.2
ports:
- "9200:9200"
environment:
ES_JAVA_OPTS: "-Xms512m -Xmx512m"
discovery.type: "single-node"
cluster.routing.allocation.disk.threshold_enabled: false
xpack.security.enabled: "false"
xpack.security.transport.ssl.enabled: "false"
TZ: "Europe/Berlin"
volumes:
- ./elasticsearch_7.10.2:/usr/share/elasticsearch/data
networks:
- graylog_network
mongo:
image: mongo:4.0
container_name: mongo
networks:
- graylog_network
volumes:
- ./mongo:/data/db
graylog:
image: graylog/graylog:4.3.0
container_name: graylog
ports:
- "9000:9000"
- "12201:12201/udp"
- "1514:1514"
environment:
GRAYLOG_HTTP_EXTERNAL_URI: "http://127.0.0.1:9000/"
GRAYLOG_PASSWORD_SECRET: "forpasswordencryption"
GRAYLOG_ROOT_PASSWORD_SHA2: "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
GRAYLOG_TIMEZONE: "Europe/Berlin"
networks:
- graylog_network
depends_on:
- elasticsearch
- mongo
mqtt_logging_handler:
image: openjdk:23-jdk-slim
container_name: mqtt_logging_handler
ports:
- "8080:8080"
volumes:
- ../Backend/mqtt_logging_handler/target:/app
- ./mqtt_logging_handler/logs:/app/logs
command: java -jar /app/quarkus-app/quarkus-run.jar
environment:
TZ: "Europe/Berlin"
networks:
- graylog_network
depends_on:
- graylog
- elasticsearch
- mongo
mqtt_for_home_assistant:
image: eclipse-mosquitto
container_name: mqtt_for_home_assistant
ports:
- "1883:1883"
networks:
- graylog_network
- docker_compose_home_assistant_network
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
environment:
TZ: "Europe/Berlin"
networks:
graylog_network:
driver: bridge
docker_compose_home_assistant_network:
external: true
2.1. Mongo
Dient als Datenbank für die Graylog Konfiguration
Bsp:
-
Users
-
Dashboard settings
~"Dient zur Haltung von Metadaten und Konfigurationen"
2.4. Home Assistent
services:
home_assistant:
image: homeassistant/home-assistant:stable
container_name: home_assistant
ports:
- "8123:8123"
networks:
- home_assistant_network
volumes:
- ./homeassistant:/config
environment:
- TZ=Europe/Berlin
restart: always
networks:
home_assistant_network:
driver: bridge
3. MQTT_Logger
mp.messaging.incoming.mqtt.connector=smallrye-mqtt
mp.messaging.incoming.mqtt.topic=#
mp.messaging.incoming.mqtt.host=mqtt_for_home_assistant
mp.messaging.incoming.mqtt.username=nik
mp.messaging.incoming.mqtt.password=nik
mp.messaging.incoming.mqtt.port=1883
mp.messaging.incoming.mqtt.qos=0
#GreyLog Config
quarkus.log.handler.gelf.enabled=true
quarkus.log.handler.gelf.host=graylog
quarkus.log.handler.gelf.port=12201
#Log Files (Log Rotation)
quarkus.log.file.enable=true
quarkus.log.level=INFO
quarkus.log.file.path=/app/logs/quarkus.log
quarkus.log.file.rotation.max-file-size=5K
quarkus.log.file.rotation.max-backup-index=3
3.1. REST-Get Logger
@Path("/hello")
public class HelloResource {
private static final Logger LOG = Logger.getLogger(MqttMessageLogger.class);
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
LOG.info("/hello was called");
return "Hello";
}
}
3.2. MQTT Logger
@ApplicationScoped
public class MqttMessageLogger {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy HH:mm:ss");
private static final Logger LOG = Logger.getLogger(MqttMessageLogger.class);
@Incoming("mqtt")
public CompletionStage<Void> onMqttMessage(Message<String> message) {
String payload = message.getPayload();
System.out.println("\n" + LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault()).format(formatter));
System.out.println("Received message: " + payload);
Optional<String> topicNameOpt = message.getMetadata()
.get(ReceivingMqttMessageMetadata.class)
.map(metadata -> metadata.getMessage().topicName());
topicNameOpt.ifPresent(topicName -> {
String logMessage = topicName + " " + payload;
System.out.println("Sent to topic: " + topicName);
if (topicName.contains("/debug")) {
LOG.debug(logMessage);
} else if (payload.contains("offline") || payload.contains("online")) {
LOG.warn(logMessage);
} else if (payload.contains("error") || payload.contains("failure")) {
LOG.error(logMessage);
} else {
LOG.info(logMessage);
}
});
return CompletableFuture.completedFuture(null);
}
}
5. Alternativen zu Graylog
5.1. ELK Stack (Elasticsearch, Logstash, Kibana)
Vorteile:
-
bekannte und weit verbreitete Lösung
-
Suchleistung ist überragend (Pfeilschnell)
-
viele Plugins
Nachteile:
-
Komplex aufzusetzen
-
ressourcenintensiv
5.2. EFK Stack (Elasticsearch, Fluentd, Kibana)
Vorteile:
-
Ressourcenschonend
-
Simpel aufzusetzen
Nachteile:
-
Weniger Möglichkeiten / Funktionen für komplexe Abfragen und Transformationen
-
Weniger verbreitet
5.3. Graylog vs Fluentd vs Logstash
Funktion | Graylog | Fluentd | Logstash |
---|---|---|---|
Hauptanwendung |
Zentralisiertes Logging und Analysefähigkeiten |
Datensammlung und -aggregation |
Datenverarbeitung und -aggregation |
Benutzerfreundlichkeit |
Benutzerfreundliche Oberfläche und eigene Dashboards |
Konfiguration über YAML-Dateien |
Erfordert benutzerdefinierte Pipelines und Konfigurationen |
Integrationen |
Eingebaute Unterstützung für ElasticSearch, MongoDB |
Breites Plugin-Ökosystem, schnelle Integration mit Kafka, o.ä. |
Umfangreiche Plugin-Bibliothek |
aggregation: Beschreibt das Sammeln und Zusammenfassen von Daten.
6. GELF + Alternativen (Graylog Extended Log Format)
{
"version": "1.1",
"host": "example.org",
"short_message": "A short message that helps you identify what is going on",
"full_message": "Backtrace here\n\nmore stuff",
"timestamp": 1385053862.3072,
"level": 1,
"_user_id": 9001,
"_some_info": "foo",
"_some_env_var": "bar"
}
7. Centralized / Decentralized Logging
7.1. Centralized Logging
Logs aus verschiedenen Quellen werden in einem Platz zusammengesammelt. Das bietet eine vereinte Suche und Analyse.
Bsp:
-
Graylog
-
ELK / EFK Stack
Vorteile:
-
leichteres Management / Monitoring
-
Real-time Analysen
Nachteile:
-
Kostenintensiv
-
braucht eine starke Netzwerk-Infrastruktur
8. Links
-
https://smallrye.io/smallrye-reactive-messaging/smallrye-reactive-messaging/3.3/mqtt/mqtt.html
-
https://stackoverflow.com/questions/38088279/communication-between-multiple-docker-compose-projects
-
https://www.reddit.com/r/devops/comments/9quyzo/from_elk_to_efk_why/?tl=de
-
https://edgedelta.com/company/blog/why-you-should-use-log-level