Skip to content
This repository was archived by the owner on Dec 14, 2022. It is now read-only.

Commit 8f64f12

Browse files
author
Chris Wiechmann
authored
Merge pull request #1 from cwiechmann/master
Majar refactoring
2 parents fafb2de + 8fe9699 commit 8f64f12

40 files changed

+6057
-12
lines changed

.env

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
1+
# Filebeat will mount that folder into the Filebeat Docker-Container to have access to the files
12
APIGATEWAY_LOGS_FOLDER=/home/localuser/Axway-x.y.z/apigateway/logs/opentraffic
23
APIGATEWAY_TRACES_FOLDER=/home/localuser/Axway-x.y.z/apigateway/groups/group-1/instance-1/trace
4+
5+
# This variable is used by the API-Builder project to locate the Elasticsearch instance
6+
# Using the default docker-compose.yaml this setting is sufficient
7+
# When running the API-Builder on a different host, this variable needs to be made available to the
8+
# container.
9+
ELASTIC_NODE=http://elasticsearch1:9200
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# This workflow is validating the API-Builder exposed Traffic-Monitor API.
2+
# For that an Elasticsearch instance is started, test-data inserted and the
3+
# API-Builder Traffic-Monitor API is executed with all possible parameters.
4+
5+
name: Test Traffic-Monitor API
6+
7+
on:
8+
push:
9+
branches: [ master ]
10+
pull_request:
11+
branches: [ master ]
12+
release:
13+
types: [ published ]
14+
15+
jobs:
16+
build:
17+
env:
18+
workingDirectory: 'elk-traffic-monitor-api'
19+
20+
runs-on: ubuntu-latest
21+
22+
strategy:
23+
matrix:
24+
node-version: [10.x, 12.x]
25+
26+
steps:
27+
- uses: actions/checkout@v2
28+
- name: Use Node.js ${{ matrix.node-version }}
29+
uses: actions/setup-node@v1
30+
with:
31+
node-version: ${{ matrix.node-version }}
32+
- name: Starting Elasticsearch instance
33+
uses: nyaruka/elasticsearch-action@v1
34+
with:
35+
elastic version: '7.6.1'
36+
- name: Sleep 30 seconds to make sure ES is ready
37+
uses: jakejarvis/wait-action@master
38+
with:
39+
time: '30s'
40+
- name: Run npm ci, npm test
41+
working-directory: ${{env.workingDirectory}}
42+
env:
43+
ELASTIC_NODE: 'http://localhost:9200'
44+
LOG_LEVEL: INFO
45+
CI: true
46+
run: |
47+
npm ci
48+
npm run build --if-present
49+
npm test
50+
publish:
51+
if: github.event.action == 'published'
52+
env:
53+
workingDirectory: 'elk-traffic-monitor-api'
54+
needs: build
55+
56+
runs-on: ubuntu-latest
57+
58+
steps:
59+
- uses: actions/checkout@v2
60+
- name: Publish Docker image
61+
uses: elgohr/Publish-Docker-Github-Action@2.13
62+
with:
63+
name: cwiechmann/elk-traffic-monitor-api
64+
workdir: ${{env.workingDirectory}}
65+
username: ${{ secrets.DOCKER_USERNAME }}
66+
password: ${{ secrets.DOCKER_PASSWORD }}
67+
snapshot: true
68+

README.md

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,121 @@
11
# API-Management Traffic-Monitor based ELK stack
22

3+
When having many API-Gateway instances with millions of requests the API-Gateway Traffic Monitor can become slow. The purpose of this project is to solve that performance issue and get other benefits by using a standard external datastore: Elasticsearch.
4+
5+
The overall architecture this project provides looks like this:
6+
![Architecture][img1]
7+
8+
### How it works
9+
Each API-Gateway instance is writing, [if configured](#enable-open-traffic-event-log), Open-Traffic Event-Log-Files, which are streamed by [Filebeat](https://www.elastic.co/beats/filebeat) into a Logstash-Instance. [Logstash](https://www.elastic.co/logstash) performs data pre-processing, combines different events and finally forwards the document into an [Elasticsearch](https://www.elastic.co/elasticsearch) cluster.
10+
11+
Once the data is indexed by Elasticsearch it can be used by different clients. This process allows almost realtime monitoring of incoming requests. It takes around 5 seconds until a request is available in Elasticsearch.
12+
13+
## Option 1 - Using the existing Traffic-Monitor
14+
One option is to use the existing API-Gateway Traffic-Monitor. That means, you use the same tooling as of today, but the underlying implementation of the Traffic-Monitor API is now pointing to Elasticsearch instead of the internal OPSDB hosted by each API-Gateway instance. This improves performance damatically, as Elasticsearch can scale across multiple machines if required and other dashboards can be created for instance with Kibana.
15+
The glue between Elasticsearch and the API-Gateway Traffic-Monitor is an API-Builder project, that is exposing the same Traffic-Monitor API, but it is implemented using Elasticsearch instead of the OPSDB. The API-Builder is available as a ready to use Docker-Image and preconfigured in the docker-compose file.
16+
Finally, the Admin-Node-Manager has to be configured to use the API-Builder API instead of the internal implementation.
17+
18+
API-Builder status:
19+
![Test Traffic-Monitor API](https://github.com/cwiechmann/apigateway-openlogging-elk/workflows/Test%20Traffic-Monitor%20API/badge.svg)
20+
21+
## Option 2 - Logspector
22+
The Logspecotr is a new separated user-interface with very basic set of functionilties. As part of the project the Logspector is activated by default when using `docker-compose up -d`. If you don't wanna use it, it can be disabled by commenting out the following lines in the docker-compose.yml file:
23+
```yaml
24+
nginx:
25+
image: nginx:1.17.6
26+
ports:
27+
- 8888:90
28+
volumes:
29+
- ${PWD}/nginx/www:/usr/share/nginx/html
30+
- ${PWD}/nginx/conf:/etc/nginx
31+
depends_on:
32+
- elasticsearch1
33+
networks:
34+
- elastic
35+
- ingress
36+
```
37+
The Log-Inspector is accessible on the following URL: `http://hostname-to-your-docker-machine:8888/logspector.html`
38+
39+
![Log-Spector][img5]
40+
41+
342
## Prerequisites
43+
For a simple deployment the prerequisites are very simple as all services can be started as a Docker-Container. In order to start all components in PoC-Like-Mode you just need:
44+
45+
1. A Docker engine
46+
2. docker-compose installed
47+
3. An API-Management Version >7.7-20200130
48+
- Versin 7.7-20200130 is required due to some Dateform changes in the Open-Traffic-Format. With older versions of the API-Gateway you will get an error in Logstash processing.
449

5-
1. docker
6-
2. docker-compose
7-
3. API-Management Version >7.7-20200130
50+
Using the provided docker-compose is good to play with, however this approach is not recommended for production environments. Depending the load a dedicated machine (node) for Elasticsearch is recommended. The default configuration is prepared to scale up to five Elasticsearch nodes, which can handle millions of requests. To run Logstash and the API-Builder service a Docker-Orchestration framework is recommended as you get monitoring, self-healing, elasticity.
51+
52+
## Installation / Configuration
53+
To run the components in a PoC-Like mode, the recommended way is to clone this project onto a machine having docker and docker-compose installed. Also this machine must have file-based access to the running API-Gateway instance, as the Filebeat docker container will mount the open-traffic folder into the docker-container.
54+
55+
`git clone https://github.com/Axway-API-Management-Plus/apigateway-openlogging-elk.git`
56+
57+
This creates a local copy of the repository and you can start from there.
58+
59+
### Enable Open-Traffic Event Log
60+
Obviously you have to enable Open-Traffic-Event log for your API-Gateway instances. [Read here][1] how to enable the Open-Traffic Event-Log.
61+
After this configuration has been done, Open-Traffic log-files will created by default in this location: `apigateway/logs/opentraffic`. This location becomes relevant in the next step, when configuring Filebeat.
62+
63+
### Configure the Admin-Node-Manager
64+
This step is required if you would like to use the existing Traffic-Monitor in combination Elasticsearch.
65+
The Admin-Node-Manager (listening by default on port 8090) is responsible to server the API-Manager Traffic-Monitor and needs to be configured to use the API-Builder API instead.
66+
For the following steps, please open the Admin-Node-Manager configuration in Policy-Studio. You can [here](https://docs.axway.com/bundle/axway-open-docs/page/docs/apim_administration/apigtw_admin/general_rbac_ad_ldap/index.html#use-the-ldap-policy-to-protect-management-services) how to do that.
67+
- Create a new policy called: `Use Elasticsearch API`
68+
- Configure this policy like so:
69+
![use ES API][img3]
70+
- The `Compare Attribute` filter checks if the requested API is already handled by the API-Builder project.
71+
_As of today, only the Traffic-Overview is handled by the API-Builder. This will be changed soon._
72+
- Add the following: `http.request.path` is `/api/router/service/instance-1/ops/search`
73+
_The list of requests will be extended once the API-Builder project can serve more (e.g. the Request-Detail view)_
74+
![Is API Managed][img6]
75+
- Adjust the URL of the Connect to URL filter to your running API-Builder docker container and port (default is 8889).
76+
![Connect to ES API][img7]
77+
- Insert the created policy as a callback policy into the main policy: `Protect Management Interfaces` like so:
78+
![Use Callback][img4]
79+
80+
After you have saved back the configuration to the Admin-Node-Manager and restarted it, the Admin-Node-Manager will use the API-Builder API (Elasticsearch) to serve the specified request-types.
81+
82+
### Setup filebeat
83+
:exclamation: __This is an important step, as otherwise Filebeat will not see and send any Open-Traffic Event data!__
84+
Before starting the container using docker-compose, make sure to setup the paths in the .env file to your running API-Gateway instance. This configuration is used to mount the Open-Traffic-Folder into Filebeat container.
85+
```
86+
APIGATEWAY_LOGS_FOLDER=/home/localuser/Axway-x.y.z/apigateway/logs/opentraffic
87+
APIGATEWAY_TRACES_FOLDER=/home/localuser/Axway-x.y.z/apigateway/groups/group-1/instance-1/trace
88+
```
89+
90+
### Setup API-Builder
91+
As the API-Builder container needs to communicate with Elasticsearch it needs to know where Elasticsearch is running. Use this environment variable to configure it:
92+
```
93+
ELASTIC_NODE=http://elasticsearch1:9200
94+
```
95+
Please note, when using the default docker-compose.yaml the default setting is sufficient, as it's using the internal Docker-Network `elastic`.
896
997
### Update vm.max_map_count kernel setting to at least 262144
1098
1199
See https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-prod-prerequisites
12100
13-
## Start local elasticsearch cluster
14-
15-
1. Edit the .env file and configure both APIGATEWAY_LOGS_FOLDER and APIGATEWAY_TRACES_FOLDER environment variables to point to your open traffic and trace folders respectively.
16-
2. Bring the cluster up using docker-compose:
101+
### Start local elasticsearch cluster
102+
Bring the cluster up using docker-compose:
17103
````
18104
docker-compose up -d
19105
````
106+
Of course, the components can also run on different machines or on a Docker-Orchestration framework such as Kubernetes.
20107
21108
## Stop cluster
22109
````
23110
docker-compose down
24111
````
25112
113+
[img1]: imgs/component-overview.png
114+
[img2]: imgs/node-manager-policies.png
115+
[img3]: imgs/node-manager-use-es-api.png
116+
[img4]: imgs/node-manager-policies-use-elasticsearch-api.png
117+
[img5]: imgs/Logspector.png
118+
[img6]: imgs/IsmanagedbyElasticsearchAPI.png
119+
[img7]: imgs/connect-to-elasticsearch-api.png
120+
121+
[1]: https://docs.axway.com/bundle/axway-open-docs/page/docs/apim_administration/apigtw_admin/admin_open_logging/index.html#configure-open-traffic-event-logging

configs/logstash.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ output {
185185
elasticsearch {
186186
hosts => "elasticsearch1:9200"
187187
index => "logstash-openlog"
188+
template => "${HOME}/pipeline/openlog_index_template.json"
189+
template_overwrite => true
188190
}
189191
} else {
190192
elasticsearch {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"index_patterns": [
3+
"*openlog*"
4+
],
5+
"settings": {
6+
"number_of_shards": 5
7+
},
8+
"mappings": {
9+
"properties": {
10+
"processInfo.serviceId": {
11+
"type": "keyword"
12+
},
13+
"transactionElements.leg0.protocolInfo.http.remoteName": {
14+
"type": "keyword"
15+
}
16+
}
17+
}
18+
}

docker-compose.yml

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
version: '3.7'
22
services:
3+
# The core component
34
elasticsearch1:
45
image: docker.elastic.co/elasticsearch/elasticsearch:7.4.0
56
container_name: elasticsearch1
@@ -26,7 +27,7 @@ services:
2627
- 9200:9200
2728
- 9300:9300
2829

29-
30+
# This is optional, but good to have to perform manual queries and create custom dashboards
3031
kibana:
3132
image: docker.elastic.co/kibana/kibana:7.4.0
3233
container_name: kibana
@@ -49,7 +50,7 @@ services:
4950
- elastic
5051
- ingress
5152

52-
53+
# Supposed to run side-by-side with the API-Gateway to watch the Open-Traffic Event files and send event to Logstash
5354
filebeat:
5455
image: docker.elastic.co/beats/filebeat:7.4.0
5556
command: --strict.perms=false
@@ -67,7 +68,7 @@ services:
6768
networks:
6869
- elastic
6970

70-
71+
# Is receiving events from Filebeat and does pre-processing
7172
logstash:
7273
image: docker.elastic.co/logstash/logstash:7.4.0
7374
links:
@@ -78,14 +79,29 @@ services:
7879
ports:
7980
- 5044:5044
8081
volumes:
81-
- ${PWD}/configs/logstash.conf:/usr/share/logstash/pipeline/default.conf
82-
command: logstash --path.config /usr/share/logstash/pipeline/default.conf --pipeline.batch.size 20 --pipeline.workers 1 --log.level info
82+
- ${PWD}/configs/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
83+
- ${PWD}/configs/openlog_index_template.json:/usr/share/logstash/pipeline/openlog_index_template.json
84+
command: logstash --path.config /usr/share/logstash/pipeline/logstash.conf --pipeline.batch.size 20 --pipeline.workers 1 --log.level info
8385
depends_on:
8486
- elasticsearch1
8587
networks:
8688
- elastic
8789

90+
# This is the API-Builder project exposing the API-Gateway Manager REST-API
91+
elk-traffic-monitor-api:
92+
image: cwiechmann/elk-traffic-monitor-api:latest
93+
links:
94+
- elasticsearch1
95+
environment:
96+
- ELASTIC_NODE=http://elasticsearch1:9200
97+
ports:
98+
- 8889:8080
99+
depends_on:
100+
- elasticsearch1
101+
networks:
102+
- elastic
88103

104+
# This is the Logspector Web-Application
89105
nginx:
90106
image: nginx:1.17.6
91107
ports:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
conf/local.js
2+
conf/*.local.js
3+
coverage
4+
.git
5+
node_modules
6+
.nyc_output
7+
conf/.env

elk-traffic-monitor-api/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
logs
3+
coverage
4+
nyc_output

elk-traffic-monitor-api/Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# See the README.md for usage and configuration info
2+
3+
# This line defines which node.js Docker image to leverage
4+
# Available versions are described at https://hub.docker.com/_/node/
5+
FROM node:8-alpine
6+
7+
# Sets the default working directory to /app which is where we copy the service files to.
8+
WORKDIR /app
9+
10+
# TODO: for security purposes, you should update this Dockerfile to specify your own target user/group
11+
# -S stands for '--system'
12+
# -G stands for group
13+
# -R changes the ownership rights of a file recursively
14+
RUN addgroup -S axway-group && adduser -S axway-user -G axway-group && \
15+
chown -R axway-user:axway-group /app
16+
17+
# Set non-root user
18+
USER axway-user
19+
20+
# Denotes to copy all files in the service to 'app' folder in the container
21+
COPY --chown=axway-user:axway-group . /app
22+
23+
# Install service dependencies relevant for production builds skipping all development dependencies.
24+
RUN npm install --production --no-optional
25+
26+
# check every 5s to ensure this service is healthy
27+
HEALTHCHECK --interval=5s --start-period=10s --timeout=5s --retries=5 CMD node healthcheck.js
28+
29+
# Starts the service
30+
CMD ["node", "."]

0 commit comments

Comments
 (0)