
Graylog: Open Source Log Management That Doesn't Make You Grep Six Servers at 3am
It’s 3am, something is broken, and you have a dozen servers. You SSH into the first one, tail -f /var/log/nginx/error.log, see nothing useful, SSH into the second one, repeat, SSH into the third one and start questioning your career choices. By the time you’ve grepped through server number seven, whatever caused the spike has already resolved itself, and you’re left with a pile of terminal tabs and no idea what actually happened.
This is exactly the problem centralized logging exists to solve, and it’s why a tool like Graylog has stuck around for over a decade. Graylog is an open source log management and analysis platform: it ingests logs from everything you run, stores them in a searchable index, and layers streams, dashboards, and alerting on top. The code lives at github.com/Graylog2/graylog2-server ; the core server ships under SSPL with some components under GPL, so licensing is a “check the specific component” situation rather than one blanket answer. We don’t run Graylog ourselves and don’t offer it as a managed service, but it’s a genuinely solid option worth a proper look if you’re evaluating what to self-host for logs.
What Graylog actually is
Graylog isn’t a single binary, it’s three pieces working together. The Graylog server is the brain: it receives incoming messages, applies whatever routing and processing rules you’ve configured, and serves the web UI and REST API. Under it sits OpenSearch or Elasticsearch, doing the actual heavy lifting of storing and indexing every message so you can search millions of lines in under a second, the same technology stack behind the “ELK” world. Alongside that sits MongoDB, easy to overlook but doing something different: it stores configuration and metadata, users, dashboards, stream definitions, alert conditions, index sets, everything describing how your instance is set up. Your logs go into OpenSearch; the rules about what happens to them live in MongoDB. This split is a defining trait of Graylog’s design, and it means you’re operating three services, not one.
Logs get in through inputs: Syslog (UDP or TCP), GELF (Graylog Extended Log Format, their own structured format built to carry more than a flat syslog line can), Beats (so Filebeat, Winlogbeat, and the rest of the Elastic Beats family ship straight into it), raw TCP/UDP, HTTP, and a handful of others. Whatever is already emitting logs on your infrastructure almost certainly has a way in.
Why it matters
When an incident spans multiple hosts, containers, or services, the question is never “what did server A log,” it’s “what happened, in order, across everything, in the two minutes around the failure.” Grepping per-host doesn’t answer that; a shared, searchable, time-correlated index does. It also means logs survive the machine that produced them: if a container gets OOM-killed and rescheduled, its logs are already somewhere else.
Centralized logging and metrics-based monitoring solve adjacent but different problems: metrics tell you something is wrong and roughly when, logs tell you what actually happened and why. Worth reading our Grafana post on the metrics side of that pairing. A mature setup tends to run both: Grafana for the “is something wrong right now” dashboards and alerts, Graylog for the “let’s find out exactly what happened” investigation afterward.
What you get out of the box
Streams route messages into logical buckets in real time based on rules you define, source, facility, a field value, a regex match. A stream isn’t a copy of the data, it’s a live filter letting a team or app see only its own slice of the firehose. Realistic example: route anything from your nginx inputs where response_code is 5xx into an “nginx-errors” stream, so the on-call dashboard only shows things actually broken.
Pipeline rules are where the real processing power lives, a small rule-based language for parsing, enriching, rewriting, or dropping messages as they arrive. Common pattern: pull an IP from an unstructured log line with a regex, do a GeoIP lookup, attach the country as a new field, before the message is indexed.
Extractors are the simpler sibling: regex or grok-style field extraction defined directly on an input, good for straightforward single-field pulls that don’t need the full pipeline language.
Search is where you’ll live day to day: a query language over indexed messages, with time range pickers and field statistics, backed by OpenSearch so it stays fast at real volume. Dashboards are built from saved searches and aggregations, error rate over time, top talkers by source IP, request volume by status code, arranged on one screen. Alerting runs on event definitions, conditions evaluated against your data (say, more than 50 events matching a stream in a 5-minute window) that trigger a notification, email, webhook, or other integration. Typical example: alert when the error rate in “nginx-errors” crosses a threshold in a rolling window, so you find out from Graylog instead of from a customer.
Graylog also sees a fair amount of security and SIEM-adjacent use: correlating events across systems, alerting on suspicious patterns. It’s genuinely useful there, but a full SIEM typically wants more than open source Graylog ships with, case management, curated detection content, threat intel feeds, which is part of what the commercial Graylog Security tier adds.
Installing Graylog on a VPS
Graylog publishes official Docker images for itself, OpenSearch, and MongoDB, so Compose is the fastest realistic path to a working instance:
services:
mongodb:
image: "mongo:6.0"
volumes:
- "mongo_data:/data/db"
restart: "on-failure"
opensearch:
image: "opensearchproject/opensearch:2.19.1"
environment:
- "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
- "bootstrap.memory_lock=true"
- "discovery.type=single-node"
- "action.auto_create_index=false"
- "plugins.security.ssl.http.enabled=false"
- "plugins.security.disabled=true"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- "opensearch_data:/usr/share/opensearch/data"
restart: "on-failure"
graylog:
image: "graylog/graylog:6.1"
environment:
GRAYLOG_PASSWORD_SECRET: "changeme-to-a-long-random-string"
GRAYLOG_ROOT_PASSWORD_SHA2: "put-a-sha256-hash-of-your-admin-password-here"
GRAYLOG_HTTP_EXTERNAL_URI: "https://logs.example.com/"
entrypoint: "/usr/bin/tini -- wait-for-it opensearch:9200 -- /docker-entrypoint.sh"
ports:
- "9000:9000/tcp"
- "1514:1514/tcp"
- "1514:1514/udp"
- "12201:12201/tcp"
- "12201:12201/udp"
depends_on:
- "mongodb"
- "opensearch"
volumes:
- "graylog_data:/usr/share/graylog/data"
restart: "on-failure"
volumes:
mongo_data:
opensearch_data:
graylog_data:
Generate the SHA256 root password hash before you start it:
echo -n "your-real-admin-password" | sha256sum
Bring it up, wait for OpenSearch and MongoDB to finish their first boot, then hit port 9000:
docker compose up -d
docker compose logs -f graylog
Once it’s reachable, lock the ports down instead of leaving everything open. You want the web UI reachable only from your admin network or behind a TLS reverse proxy, and log-shipping ports open only to the hosts that actually send you logs:
ufw allow from 203.0.113.0/24 to any port 9000 proto tcp comment "Graylog web UI, admin network only"
ufw allow from 10.0.0.0/16 to any port 1514 proto tcp comment "Syslog TCP, internal hosts"
ufw allow from 10.0.0.0/16 to any port 1514 proto udp comment "Syslog UDP, internal hosts"
ufw allow from 10.0.0.0/16 to any port 12201 comment "GELF, internal hosts"
ufw deny 9000
ufw deny 1514
ufw deny 12201
This is exactly the kind of workload a VPS handles well: not huge on its own, but running three services means you want a machine with real, dedicated memory rather than a burstable micro instance where OpenSearch will fight you for RAM. A DreamServer VPS with a few gigabytes to spare is a reasonable start for small to medium log volume; scale the OpenSearch heap and disk as retention needs grow.
Configuration patterns worth knowing
Index rotation and retention. Graylog organizes indices into “index sets” with rotation strategies (by size or time) and retention strategies deciding when old indices close, archive, or get deleted. Get this wrong and you either burn disk on data nobody looks at, or rotate so aggressively you lose the history you needed during an incident review. Set retention deliberately per index set, not as an afterthought once disk alerts start firing.
Streams as team and application boundaries. Rather than one giant firehose everyone stares at, use streams to give each team or app its own slice, a “database” stream, a “web” stream, a “security” stream. Streams can carry their own retention settings and access permissions, so a team gets visibility into its own logs without the whole cluster’s data.
Pipeline rules versus extractors. Extractors are simpler and live on the input itself, good for a quick single-field pull with no conditional logic. Pipeline rules are the right tool once you need conditionals, multiple transformations, GeoIP or lookup-table enrichment, or routing decisions based on parsed content. Rule of thumb: if you’re writing more than one extractor to handle variations of the same message, move that logic into a pipeline rule instead.
Securing the web interface. Graylog ships its own user and role system, but beyond a single admin, plan access control deliberately: separate admin accounts from read-only viewer roles, and don’t expose port 9000 to the open internet without TLS in front of it. If you already run centralized auth elsewhere, check Graylog’s authentication provider options before adding local users.
Where Graylog is not the right answer
If you’re running one or two servers, journalctl and rotated log files with grep/awk genuinely cover most needs, and running Graylog, OpenSearch, and MongoDB just to watch logs from one box is a lot of operational overhead for very little payoff.
If your team already runs an Elastic/OpenSearch stack for other purposes (product search, analytics), adding Graylog on top means a second thing to operate against data infrastructure you already have, and it may make more sense to build log ingestion directly into what you’ve got.
Resource overhead is real: three services, each with their own memory and disk footprint, is meaningfully more than a single log aggregator binary, and OpenSearch wants real memory to stay fast. For small workloads this can be disproportionate to the problem you’re solving.
And if you actually need a SIEM with compliance-grade case management, curated detection content, and threat intelligence feeds, the open source edition alone won’t get you there; that’s the gap the commercial Graylog Security tier exists to fill.
Alternatives we considered
The Elastic Stack (elastic.co ), Elasticsearch, Logstash, Kibana, is the platform Graylog’s own storage layer is adjacent to. If you’re already invested in Elastic tooling or need Kibana’s visualization ecosystem, running the stack directly rather than through Graylog’s abstraction is reasonable, though you lose Graylog’s ops-friendly streams and pipeline UI and take on Elastic’s own licensing considerations.
Loki with Grafana (grafana.com/oss/loki ) indexes only metadata labels instead of full log content, treating log bodies as compressed, unindexed blobs, dramatically cheaper to run at scale. The tradeoff is search flexibility: broad full-text search isn’t Loki’s strong suit the way it is Graylog’s. If you’re already all-in on Grafana for metrics, Loki slots in naturally without adding a new infrastructure paradigm.
SigNoz is a newer open source observability platform bundling logs, metrics, and traces on top of ClickHouse, appealing if you want one platform covering all three signals from day one, though it’s a younger project with a smaller community and less operational history than Graylog or the Elastic stack.
So, should you run it?
If you’ve got more than a couple of servers and you’re tired of SSHing around at 3am reconstructing what happened, centralized logging earns its keep fast, and Graylog is a mature, capable way to do it: solid ingestion options, a real processing pipeline, search that stays usable at volume. Go in with eyes open about the three-service footprint, size OpenSearch properly for your log volume, and decide your retention strategy before disk usage forces the decision for you.
If you’re weighing where to run this, a DreamServer VPS gives you the dedicated resources this workload wants without over-provisioning for a small deployment, and if you’d rather not own the operational side of keeping Docker, OpenSearch heap sizes, and index retention healthy long-term, our server administration services cover exactly that kind of ongoing care.