Graylog Cheatsheet
Installation
| Platform | Installation Method |
|---|
| Ubuntu/Debian | wget https://packages.graylog2.org/repo/packages/graylog-5.2-repository_latest.deb && sudo dpkg -i graylog-5.2-repository_latest.deb && sudo apt-get update && sudo apt-get install graylog-server |
| CentOS/RHEL | sudo rpm -Uvh https://packages.graylog2.org/repo/packages/graylog-5.2-repository_latest.rpm && sudo yum install graylog-server |
| Docker | docker run -d --name graylog -p 9000:9000 -p 12201:12201 -p 1514:1514 -e GRAYLOG_PASSWORD_SECRET="somepassword" -e GRAYLOG_ROOT_PASSWORD_SHA2="hash" graylog/graylog:5.2 |
| Docker Compose | curl -O https://raw.githubusercontent.com/Graylog2/graylog-docker/5.2/docker-compose.yml && docker-compose up -d |
| Kubernetes (Helm) | helm repo add graylog https://charts.graylog.org/ && helm install graylog graylog/graylog --namespace graylog |
Prerequisites Installation
| Component | Command |
|---|
| Java (OpenJDK 17) | sudo apt-get install openjdk-17-jre-headless |
| MongoDB 6.0 | sudo apt-get install mongodb-org |
| OpenSearch 2.x | wget https://artifacts.opensearch.org/releases/bundle/opensearch/2.11.0/opensearch-2.11.0-linux-x64.deb && sudo dpkg -i opensearch-2.11.0-linux-x64.deb |
| Verify Java | java -version |
Service Management Commands
| Command | Description |
|---|
sudo systemctl start graylog-server | Start Graylog service |
sudo systemctl stop graylog-server | Stop Graylog service |
sudo systemctl restart graylog-server | Restart Graylog service |
sudo systemctl status graylog-server | Check service status |
sudo systemctl enable graylog-server | Enable service at boot |
sudo systemctl disable graylog-server | Disable service at boot |
sudo tail -f /var/log/graylog-server/server.log | View live logs |
sudo journalctl -u graylog-server -f | View systemd journal logs |
sudo systemctl daemon-reload | Reload systemd configuration |
REST API - Authentication & Setup
| Command | Description |
|---|
curl -X POST 'http://localhost:9000/api/system/sessions' -H 'Content-Type: application/json' -d '{"username":"admin","password":"pass","host":"localhost"}' | Create session token |
curl -u admin:token http://localhost:9000/api/system | Test API connection with token |
curl -u admin:token http://localhost:9000/api/system/cluster/nodes | List cluster nodes |
curl -u admin:token http://localhost:9000/api/system/cluster/node | Get current node info |
curl -u admin:token http://localhost:9000/api/system/indexer/cluster/health | Check Elasticsearch health |
export GRAYLOG_API="http://localhost:9000/api" | Set API endpoint variable |
export GRAYLOG_TOKEN="your-api-token" | Set authentication token |
REST API - Search Operations
| Command | Description |
|---|
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/relative?query=*&range=3600&limit=100" | Search all logs (last hour) |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/relative?query=source:webserver&range=3600" | Search by source field |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/relative?query=level:error&range=86400" | Search error logs (24h) |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/absolute?query=*&from=2024-01-01T00:00:00.000Z&to=2024-01-02T00:00:00.000Z" | Search with absolute time range |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/relative?query=message:*failed*&range=3600&sort=timestamp:desc" | Search with keyword and sort |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/relative?query=http_status:500&range=7200" | Search by HTTP status code |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/search/universal/relative?query=source:nginx%20AND%20level:error&range=3600" | Boolean search query |
| Command | Description |
|---|
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/inputs" | List all inputs |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/inputs" -H 'Content-Type: application/json' -d '{"title":"Syslog UDP","type":"org.graylog2.inputs.syslog.udp.SyslogUDPInput","global":true,"configuration":{"port":1514}}' | Create Syslog UDP input |
curl -X DELETE -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/inputs/{inputId}" | Delete input by ID |
curl -X PUT -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/inputs/{inputId}" | Update input configuration |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/inputs/{inputId}" | Get specific input details |
REST API - Stream Management
| Command | Description |
|---|
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/streams" | List all streams |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/streams" -H 'Content-Type: application/json' -d '{"title":"Security Logs","description":"Security events","rules":[]}' | Create new stream |
curl -X DELETE -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/streams/{streamId}" | Delete stream |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/streams/{streamId}/resume" | Start/resume stream |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/streams/{streamId}/pause" | Pause stream |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/streams/{streamId}/rules" | List stream rules |
REST API - Index Management
| Command | Description |
|---|
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/indices/index_sets" | List index sets |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/indices/ranges" | List index ranges |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/indices/ranges/rebuild" | Rebuild index ranges |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/indices/{indexName}/reopen" | Reopen closed index |
curl -X DELETE -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/indices/indices/{indexName}" | Delete specific index |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/system/indexer/indices/closed" | List closed indices |
REST API - Alert & Notification Management
| Command | Description |
|---|
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/events/definitions" | List event definitions |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/events/notifications" | List notification configurations |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/events/definitions" -H 'Content-Type: application/json' -d @event_definition.json | Create event definition |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/events/search" | Search events |
curl -X DELETE -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/events/definitions/{definitionId}" | Delete event definition |
REST API - User & Role Management
| Command | Description |
|---|
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/users" | List all users |
curl -X POST -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/users" -H 'Content-Type: application/json' -d '{"username":"newuser","password":"pass","email":"user@example.com","permissions":[],"roles":["Reader"]}' | Create new user |
curl -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/roles" | List all roles |
curl -X DELETE -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/users/{username}" | Delete user |
curl -X PUT -u $GRAYLOG_TOKEN:token "$GRAYLOG_API/users/{username}/password" -H 'Content-Type: application/json' -d '{"password":"newpass"}' | Change user password |
Configuration Files
Main Server Configuration
Location: /etc/graylog/server/server.conf
# Core settings
is_leader = true
node_id_file = /etc/graylog/server/node-id
password_secret = <96-character-secret>
root_password_sha2 = <sha256-hash>
# Web interface
http_bind_address = 0.0.0.0:9000
http_publish_uri = http://graylog.example.com:9000/
http_external_uri = http://graylog.example.com:9000/
# Elasticsearch/OpenSearch
elasticsearch_hosts = http://127.0.0.1:9200
rotation_strategy = count
elasticsearch_max_docs_per_index = 20000000
elasticsearch_max_number_of_indices = 20
retention_strategy = delete
# MongoDB
mongodb_uri = mongodb://localhost:27017/graylog
# Email configuration
transport_email_enabled = true
transport_email_hostname = smtp.example.com
transport_email_port = 587
transport_email_use_auth = true
transport_email_auth_username = graylog@example.com
transport_email_auth_password = password
transport_email_from_email = graylog@example.com
# Message processing
processbuffer_processors = 5
outputbuffer_processors = 3
processor_wait_strategy = blocking
ring_size = 65536
inputbuffer_ring_size = 65536
inputbuffer_processors = 2
inputbuffer_wait_strategy = blocking
# Message journal
message_journal_enabled = true
message_journal_dir = /var/lib/graylog-server/journal
message_journal_max_size = 5gb
JVM Options
Location: /etc/graylog/server/server.conf or JVM options file
# Heap size (set to 50% of available RAM, max 32GB)
-Xms4g
-Xmx4g
# Garbage collection
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:ParallelGCThreads=4
-XX:ConcGCThreads=2
# Memory settings
-XX:+AlwaysPreTouch
-XX:+UseStringDeduplication
Log4j Configuration
Location: /etc/graylog/server/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="org.graylog2.log4j">
<Appenders>
<RollingFile name="rolling-file" fileName="/var/log/graylog-server/server.log"
filePattern="/var/log/graylog-server/server.log.%i.gz">
<PatternLayout pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %-5p [%c{1}] %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="rolling-file"/>
</Root>
</Loggers>
</Configuration>
Common Use Cases
# 1. Create Syslog UDP input via API
curl -X POST -u admin:token http://localhost:9000/api/system/inputs \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"title": "Linux Syslog UDP",
"type": "org.graylog2.inputs.syslog.udp.SyslogUDPInput",
"global": true,
"configuration": {
"bind_address": "0.0.0.0",
"port": 1514,
"recv_buffer_size": 262144
}
}'
# 2. Configure rsyslog on client server
echo "*.* @graylog-server:1514;RSYSLOG_SyslogProtocol23Format" | \
sudo tee /etc/rsyslog.d/90-graylog.conf
# 3. Restart rsyslog
sudo systemctl restart rsyslog
# 4. Test log forwarding
logger -p local0.info "Test message to Graylog"
# 5. Search for test message
curl -u admin:token \
"http://localhost:9000/api/search/universal/relative?query=message:*Test*&range=300"
Use Case 2: Creating Security Event Stream with Alerts
# 1. Create security stream
STREAM_ID=$(curl -X POST -u admin:token http://localhost:9000/api/streams \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"title": "Security Events",
"description": "Failed logins and security violations",
"remove_matches_from_default_stream": false,
"index_set_id": "default"
}' | jq -r '.stream_id')
# 2. Add stream rule for failed SSH logins
curl -X POST -u admin:token \
"http://localhost:9000/api/streams/$STREAM_ID/rules" \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"field": "message",
"type": 1,
"value": "Failed password",
"inverted": false,
"description": "SSH failed login attempts"
}'
# 3. Start the stream
curl -X POST -u admin:token \
"http://localhost:9000/api/streams/$STREAM_ID/resume" \
-H 'X-Requested-By: cli'
# 4. Create email notification
curl -X POST -u admin:token http://localhost:9000/api/events/notifications \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"title": "Security Alert Email",
"description": "Email notification for security events",
"config": {
"type": "email-notification-v1",
"recipients": ["security@example.com"],
"subject": "Security Alert: ${event.message}",
"body_template": "Event: ${event.message}\nTimestamp: ${event.timestamp}"
}
}'
# 1. Create GELF TCP input for application logs
curl -X POST -u admin:token http://localhost:9000/api/system/inputs \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"title": "Application GELF TCP",
"type": "org.graylog2.inputs.gelf.tcp.GELFTCPInput",
"global": true,
"configuration": {
"bind_address": "0.0.0.0",
"port": 12201,
"recv_buffer_size": 1048576
}
}'
# 2. Send test application log (using Python)
cat > send_log.py << 'EOF'
import logging
import graypy
logger = logging.getLogger('test_app')
logger.setLevel(logging.INFO)
handler = graypy.GELFTCPHandler('graylog-server', 12201)
logger.addHandler(handler)
logger.info('Application started', extra={
'environment': 'production',
'service': 'api',
'version': '1.0.0'
})
EOF
python3 send_log.py
# 3. Create stream for application errors
curl -X POST -u admin:token http://localhost:9000/api/streams \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"title": "Application Errors",
"description": "Application error logs",
"rules": [{
"field": "level",
"type": 1,
"value": "3",
"inverted": false
}]
}'
Use Case 4: Dashboard Creation and Export
# 1. List available dashboards
curl -u admin:token http://localhost:9000/api/dashboards
# 2. Create new dashboard
DASHBOARD_ID=$(curl -X POST -u admin:token http://localhost:9000/api/dashboards \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"title": "System Overview",
"description": "System metrics and logs"
}' | jq -r '.dashboard_id')
# 3. Add widget to dashboard (message count)
curl -X POST -u admin:token \
"http://localhost:9000/api/dashboards/$DASHBOARD_ID/widgets" \
-H 'Content-Type: application/json' \
-H 'X-Requested-By: cli' \
-d '{
"description": "Total Messages",
"type": "SEARCH_RESULT_COUNT",
"cache_time": 10,
"config": {
"timerange": {
"type": "relative",
"range": 3600
},
"query": "*",
"stream_id": null
}
}'
# 4. Export dashboard configuration
curl -u admin:token \
"http://localhost:9000/api/dashboards/$DASHBOARD_ID" \
> dashboard_backup.json
Use Case 5: Index Management and Optimization
# 1. Check current index status
curl -u admin:token http://localhost:9000/api/system/indices/index_sets
# 2. Get index statistics
curl -u admin:token http://localhost:9000/api/system/indexer/indices/closed
# 3. Optimize old indices
curl -X POST -u admin:token \
http://localhost:9000/api/system/indexer/indices/graylog_0/optimize \
-H 'X-Requested-By: cli'
# 4. Close old indices manually
curl -X POST -u admin:token \
http://localhost:9000/api/system/indexer/indices/graylog_0/close \
-H 'X-Requested-By: cli'
# 5. Delete old indices (be careful!)
curl -X DELETE -u admin:token \
http://localhost:9000/api/system/indexer/indices/indices/graylog_0 \
-H 'X-Requested-By: cli'
# 6. Trigger index rotation
curl -X POST -u admin:token \
http://localhost:9000/api/system/indices/index_sets/default/rotation \
-H 'X-Requested-By: cli'
# 7. Rebuild index ranges (after maintenance)
curl -X POST -u admin:token \
http://localhost:9000/api/system/indices/ranges/rebuild \
-H 'X-Requested-By: cli'
Search Query Syntax
| Query Type | Example | Description |
|---|
| Simple text | error | Search for “error” in any field |
| Field search | source:webserver | Search specific field |
| Phrase search | "connection refused" | Exact phrase match |
| Boolean AND | error AND database | Both terms must exist |
| Boolean OR | error OR warning | Either term exists |
| Boolean NOT | error NOT timeout | Exclude term |
| Wildcard | err* | Matches error, errors, etc. |
| Range (numeric) | http_status:[400 TO 599] | Numeric range |
| Range (date) | timestamp:[2024-01-01 TO 2024-01-31] | Date range |
| Exists | _exists_:user_id | Field exists |
| Regex | message:/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ | Regular expression |
| Grouping | (error OR warning) AND source:app | Grouped conditions |
| Greater than | response_time:>1000 | Numeric comparison |
| Less than | response_time:<100 | Numeric comparison |
Pipeline Rules (Advanced Processing)
Common Pipeline Rule Examples
// Extract HTTP status code from message
rule "extract_http_status"
when
has_field("message")
then
let pattern = "HTTP/\\d\\.\\d\" (\\d{3})";
let result = regex(pattern: pattern, value: to_string($message.message));
set_field("http_status", result["0"]);