Skip to content

Commit b192ace

Browse files
committed
add logstash files
1 parent 750bf4e commit b192ace

File tree

9 files changed

+174
-50
lines changed

9 files changed

+174
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
venv/
22
.idea
3+
.DS_Store

logstash/db-enrichment/Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,3 @@ up:
33

44
down:
55
docker-compose down
6-
7-
test:
8-
./test.sh

logstash/db-enrichment/README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# DB Enrichment Project
2+
3+
This project sets up a local environment for enriching logs with data from a PostgreSQL database using Logstash. The setup includes Docker containers for Logstash and PostgreSQL, along with the necessary configuration files and scripts. The purpose of this project is to test JDBC connection string parameters to avoid Logstash's bad behavior when the PostgreSQL table is locked or slow.
4+
5+
The following sections provide detailed instructions on how to set up and use the provided Docker containers, as well as how to send logs for enrichment.
6+
7+
```bash
8+
├── Makefile # Docker-compose shortcut (up|down)
9+
├── docker-compose.yaml # Docker-compose manifest file
10+
├── logstash
11+
│   ├── Dockerfile # Logstash Dockerfile
12+
│   ├── config
13+
│   │   ├── logstash.yml # Logstash configuration file
14+
│   │   └── pipelines.yml # Logstash pipelines configuration
15+
│   └── pipeline
16+
│   └── pipeline.cfg # Main Logstash pipeline configuration
17+
├── postgres
18+
│   └── init.sql # PostgreSQL initialization script
19+
└── send-log.sh # Script to send logs to Logstash
20+
```
21+
22+
# Set up the containers
23+
24+
To start the containers, use the following command:
25+
26+
```bash
27+
make up
28+
```
29+
30+
To stop the containers, use the following command:
31+
32+
```bash
33+
make down
34+
```
35+
36+
# Send logs
37+
38+
The script [send-log.sh](./send-log.sh) is used to send logs to Logstash through HTTP. There are two types of logs: enriched logs and non-enriched logs.
39+
40+
To send logs that will be enriched from the database, use the following command:
41+
42+
```shell
43+
./send-log.sh db
44+
```
45+
46+
To send logs that will not be enriched, use the following command:
47+
48+
```shell
49+
./send-log.sh
50+
```
51+
52+
# JDBC String Connection Details
53+
54+
More details about JDBC_CONNECTION_STRING parameters:
55+
56+
- https://jdbc.postgresql.org/documentation/use/
57+
- https://www.postgresql.org/docs/current/runtime-config-client.html
58+
59+
JDBC connection string used in this stack:
60+
61+
```
62+
jdbc:postgresql://postgres:5432/db?ApplicationName=logstash&loginTimeout=10&socketTimeout=10&options=-c%20statement_timeout=5000%20-c%20lock_timeout=1000
63+
```
64+
65+
- `ApplicationName=logstash`: Sets the application name to "logstash" for easier identification in PostgreSQL logs.
66+
- `loginTimeout=10`: Specifies the maximum time in seconds to wait for a connection to be established. If the connection cannot be established within this time, an error is thrown.
67+
- `socketTimeout=10`: Sets the maximum time in seconds for reading data from the database. If the database does not respond within this time, the connection is closed.
68+
- `options=-c statement_timeout=5000 -c lock_timeout=1000`: Passes additional configuration parameters to PostgreSQL:
69+
- `statement_timeout=5000`: Sets the maximum time in milliseconds that a query can run before being terminated. In this case, queries running longer than 5 seconds will be aborted.
70+
- `lock_timeout=1000`: Sets the maximum time in milliseconds to wait for a lock on a table. If the lock cannot be acquired within 1 second, an error is thrown.
71+
72+
# SQL Command to Lock Table
73+
74+
With auto-commit off, when you execute the command below, the table will be locked. When you commit, the table will be unlocked.
75+
76+
```sql
77+
LOCK TABLE table_users IN ACCESS EXCLUSIVE MODE;
78+
```
79+
80+
# How to Simulate a Slow Query
81+
82+
To test how Logstash handles slow queries, you can simulate a delay in the PostgreSQL response using the `pg_sleep` function. This function pauses the execution for a specified number of seconds. In the example below, the query will sleep for 7 seconds before returning the results.
83+
84+
Use the following SQL command to simulate a slow query:
85+
86+
```sql
87+
SELECT
88+
pg_sleep(7)::text,
89+
user_name,
90+
user_email,
91+
user_group
92+
FROM table_users
93+
WHERE id = ?
94+
```
95+
96+
In this query:
97+
- `pg_sleep(7)::text` introduces a 7-second delay.
98+
- `user_name`, `user_email`, and `user_group` are the columns being retrieved from the `table_users` table.
99+
- `id = ?` is a placeholder for the user ID you want to query.
100+
101+
This setup helps you observe how Logstash behaves when the database query takes longer to execute.

logstash/db-enrichment/docker-compose.yaml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,21 @@ services:
1313
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
1414

1515
logstash:
16-
image: docker.elastic.co/logstash/logstash:8.11.2
1716
container_name: logstash
1817
restart: always
1918
build:
2019
context: logstash
20+
args:
21+
LOGSTASH_IMAGE: docker.elastic.co/logstash/logstash-oss:8.9.2
22+
JDBC_JAR_DOWNLOAD_URL: https://jdbc.postgresql.org/download/postgresql-42.5.0.jar
2123
environment:
2224
DB_USER: user
2325
DB_PASSWORD: password
24-
DB_JDBC_CONNECTION_STRING: jdbc:postgresql://postgres:5432/users_logs
25-
# DB_JDBC_CONNECTION_STRING: jdbc:postgresql://postgres:5432/users_logs?ApplicationName=logstash&loginTimeout=10&socketTimeout=10&options=-c%20statement_timeout=5000%20-c%20lock_timeout=1000
26+
# DB_JDBC_CONNECTION_STRING: jdbc:postgresql://postgres:5432/db
27+
DB_JDBC_CONNECTION_STRING: jdbc:postgresql://postgres:5432/db?ApplicationName=logstash&loginTimeout=10&socketTimeout=10&options=-c%20statement_timeout=5000%20-c%20lock_timeout=1000
2628
ports:
2729
- 8090:8090
2830
volumes:
2931
- ./logstash/pipeline:/usr/share/logstash/pipeline
3032
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
3133
- ./logstash/config/pipelines.yml:/usr/share/logstash/config/pipelines.yml
32-
33-
adminer:
34-
image: adminer
35-
container_name: adminer
36-
restart: always
37-
ports:
38-
- "8080:8080"
39-
environment:
40-
ADMINER_DEFAULT_SERVER: postgres
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
FROM docker.elastic.co/logstash/logstash:8.9.2
1+
# Define build arguments the specified Logstash image
2+
ARG LOGSTASH_IMAGE
3+
FROM ${LOGSTASH_IMAGE}
24

5+
# Set the working directory to /usr/share/logstash
36
WORKDIR /usr/share/logstash
47

5-
RUN curl -o /usr/share/logstash/postgresql-42.5.0.jar https://jdbc.postgresql.org/download/postgresql-42.5.0.jar
8+
# Download the PostgreSQL JDBC driver and save it as postgresql.jar in the working directory
9+
ARG JDBC_JAR_DOWNLOAD_URL
10+
RUN curl -L "${JDBC_JAR_DOWNLOAD_URL}" -o /usr/share/logstash/postgresql.jar
Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# SQL command to lock table
2+
# lock table table_users IN ACCESS exclusive mode;
3+
14
input {
25
http {
36
port => 8090
@@ -11,39 +14,46 @@ input {
1114

1215
filter {
1316
mutate {
14-
remove_field => ["headers"]
17+
remove_field => ["headers", "original", "event", "host"]
1518
}
1619

17-
jdbc_streaming {
18-
jdbc_connection_string => "${DB_JDBC_CONNECTION_STRING}"
19-
jdbc_user => "${DB_USER}"
20-
jdbc_password => "${DB_PASSWORD}"
21-
jdbc_validate_connection => true
22-
jdbc_validation_timeout => 1
23-
jdbc_driver_library => "/usr/share/logstash/postgresql-42.5.0.jar"
24-
jdbc_driver_class => "org.postgresql.Driver"
25-
# https://github.com/jeremyevans/sequel/blob/master/doc/opening_databases.rdoc#top
26-
# sequel_opts => {
27-
# max_connections => 4
28-
# pool_timeout => 5
29-
# }
30-
# pg_sleep(10)::text,
31-
statement => "
32-
SELECT
33-
user_name,
34-
user_email,
35-
user_group
36-
FROM db_users
37-
WHERE id = :input_parameter
38-
"
39-
parameters => {
40-
"input_parameter" => "[document][user_id]"
20+
if [document][user_id] {
21+
22+
jdbc_streaming {
23+
jdbc_driver_library => "/usr/share/logstash/postgresql.jar"
24+
jdbc_driver_class => "org.postgresql.Driver"
25+
jdbc_connection_string => "${DB_JDBC_CONNECTION_STRING}"
26+
jdbc_user => "${DB_USER}"
27+
jdbc_password => "${DB_PASSWORD}"
28+
use_prepared_statements => true
29+
prepared_statement_name => "logstash_enrich_query"
30+
prepared_statement_bind_values => ["[document][user_id]"]
31+
statement => "
32+
SELECT
33+
user_name,
34+
user_email,
35+
user_group
36+
FROM table_users
37+
WHERE id = ?
38+
"
39+
target => "sql"
4140
}
42-
target => "sql"
41+
4342
}
4443

4544
}
4645

4746
output {
4847
stdout { codec => rubydebug }
48+
# stdout { codec => json }
4949
}
50+
51+
# jdbc_validate_connection => true
52+
# jdbc_validation_timeout => 1
53+
# https://github.com/jeremyevans/sequel/blob/master/doc/opening_databases.rdoc#top
54+
# sequel_opts => {
55+
# max_connections => 4
56+
# pool_timeout => 5
57+
# }
58+
# pg_sleep(10)::text,
59+

logstash/db-enrichment/postgres/init.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
CREATE DATABASE users_logs;
1+
CREATE DATABASE db;
22

3-
\c users_logs;
3+
\c db;
44

5-
CREATE TABLE db_users (
5+
CREATE TABLE table_users (
66
id SERIAL PRIMARY KEY,
77
user_name VARCHAR(100) NOT NULL,
88
user_email VARCHAR(100) NOT NULL UNIQUE,
99
user_group VARCHAR(50) NOT NULL
1010
);
1111

12-
INSERT INTO db_users (user_name, user_email, user_group) VALUES
12+
INSERT INTO table_users (user_name, user_email, user_group) VALUES
1313
('Alice Silva', '[email protected]', 'admin'),
1414
('Bruno Costa', '[email protected]', 'user'),
1515
('Carlos Mendes', '[email protected]', 'user'),

logstash/db-enrichment/send-log.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
# Set the URL and headers
4+
URL="http://127.0.0.1:8090/"
5+
HEADER="Content-Type: application/json"
6+
7+
# Function to send a POST request
8+
send_post_request() {
9+
local payload=$1
10+
curl -X POST "$URL" \
11+
-H "$HEADER" \
12+
-d "$payload"
13+
}
14+
15+
# Send the appropriate payload based on the argument
16+
if [[ "$1" == "db" ]]; then
17+
send_post_request '{"event": "purchase", "user_id": 3}'
18+
else
19+
send_post_request '{"event": "no database query"}'
20+
fi

logstash/db-enrichment/test.sh

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)