Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions .github/workflows/logging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Deploy Elasticsearch, Install Fluentd and Configure

on:
push:
branches:
- main
paths:
- '.github/workflows/logging.yml'


jobs:
deploy_elasticsearch_install_and_configure_fluentd:
runs-on: ubuntu-latest
env:
CLUSTER_NAME: ${{ secrets.ELASTICSEARCH_CLUSTER_NAME }}
ELASTICSEARCH_HOST: ${{ secrets.ELASTICSEARCH_HOST }}
ELASTICSEARCH_PORT: ${{ secrets.ELASTICSEARCH_PORT }}
ELASTICSEARCH_USERNAME: ${{ secrets.ELASTICSEARCH_USERNAME }}
ELASTICSEARCH_PASSWORD: ${{ secrets.ELASTICSEARCH_PASSWORD }}


steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Check if Fluentd is installed
id: check_fluentd
run: |
if ! command -v td-agent &> /dev/null
then
echo "::set-output name=installed:: false"
else
echo "::set-output name=installed::true"
fi

- name: Install Fluentd, copy config file, start service and open ports
if: steps.check_fluentd.outputs.installed == 'false'
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: |
sudo apt-get update
sudo apt-get install -y gnupg2 curl
curl -sSL https://toolbelt.treasuredata.com/sh/install-ubuntu-focal-td-agent4.sh | sudo sh
cp fluentd.conf /etc/td-agent/fluentd.conf
sudo systemctl start td-agent
- name: Copy Config file to server and open ports
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: |
sudo cp /etc/td-agent/fluentd.conf /etc/td-agent/fluentd.conf.bak
sudo cp fluentd.conf /etc/td-agent/fluentd.conf
sudo systemctl restart td-agent
sudo systemctl status td-agent
fluentd -c in_docker.conf
- name: Open specified ports on the server
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: |
sudo ufw allow 9200 # Allow traffic on Elasticsearch port
sudo ufw allow 9300 # Allow traffic on Elasticsearch port(inter-node communication)
sudo ufw allow 5601 # Allow traffic on Kibana port
sudo ufw reload # Reload firewall to apply changes
- name: Create Docker volume for Elasticsearch data
run: docker volume create elasticsearch_data

- name: Run Elasticsearch container with volume mount
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
script: |
docker run -d --name elasticsearch \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "cluster.name=${{ env.CLUSTER_NAME }}" \
-v elasticsearch_data:/var/lib/elasticsearch/data
-v :/var/lib/elasticsearch/logs \
--restart=always \
docker.elastic.co/elasticsearch/elasticsearch:8.12.2
- name: Wait for Elasticsearch to start
run: docker exec elasticsearch sh -c 'until curl -sSf localhost:9200; do sleep 1; done'

- name: Create and apply Index Lifesycle Management Policy(ILM) policy
run: |
curl -X PUT "localhost:9200/_ilm/policy/one_year_policy" -H 'Content-Type: application/json' -d'
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_age": "30d"
}
}
},
"delete": {
"min_age": "365d",
"actions": {
"delete": {}
}
}
}
}
}'
curl -X PUT "localhost:9200/fluentd/_settings" -H 'Content-Type: application/json' -d'
{
"index": {
"lifecycle": {
"name": "one_year_policy"
}
}
}'
- name: Run Kibana Container
run: |
docker run -d --name kibana \
-p 5601:5601 \
-e "ELASTICSEARCH_USERNAME=${{ secrets.ELASTICSEARCH_USERNAME }}" \
-e "ELASTICSEARCH_PASSWORD=${{ secrets.ELASTICSEARCH_PASSWORD }}" \
-e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" \
--restart=always \
docker.elastic.co/kibana/kibana:8.12.2
- name: Wait for Kibana to start
run: docker exec kibana sh -c 'until curl -sSf localhost:5601; do sleep 1; done'
27 changes: 27 additions & 0 deletions fluentd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Input Plugin: Docker Logs
<source>
@type docker
tag docker.*
@log_level debug
@log_opts ["env=production"]
</source>

# Filter Plugin: (Optional) Parse and Enrich Logs
<filter docker.**>
@type parser
key_name log
<parse>
@type json
</parse>
</filter>

# Output Plugin: Send Logs to Elasticsearch
<match docker.**>
@type elasticsearch
host "#{ENV['ELASTICSEARCH_HOST']}"
port "#{ENV['ELASTICSEARCH_PORT']}"
index_name fluentd
type_name _doc
include_tag_key true
tag_key @log_name
</match>
3 changes: 3 additions & 0 deletions helpers/awardBadge.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const logger = require("./logger");
const badgeLink =
"https://raw.githubusercontent.com/badging/badging/main/src/assets/images/badges/bronze-badge.svg";

Expand Down Expand Up @@ -29,6 +30,8 @@ const awardBadge = async (octokit, owner, repoName) => {
});

console.log("Badge added to README successfully.");
// Log success message
logger.info("Badge added to README successfully.", { owner, repoName });
} catch (error) {
console.error("Error awarding badge:", error);
}
Expand Down
19 changes: 19 additions & 0 deletions logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const winston = require("winston");

// Create a Winston logger
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(), // Add timestamp to log messages
winston.format.json() // Use JSON format for log messages
),
transports: [
new winston.transports.Http({
host: "localhost",
port: 24224, // Fluentd port
path: "/debug.fluentd", // Fluentd input path
ssl: false, // Use SSL if required
}),
],
});

module.exports = logger;
60 changes: 60 additions & 0 deletions loggerauth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const express = require("express");
const session = require("express-session");
const logger = require("./logger");
const router = express.Router();

router.use(express.urlencoded({ extended: true }));
router.use(
session({
secret: "my-secret",
resave: false,
saveUninitialized: true,
})
);

router.get("/logs", (req, res) => {
logger.info("Admin user accessed login page");
res.send(`
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username"><br><br>
<label for="password">Password:</label>
input type="password" id="password" name="password"><br><br>
<button type="submit">Login</button>
</form>
`);
});

//Authentication
router.post("/logs/login", (req, res) => {
const { username, password } = req.body;
const validUsername = process.env.ELASTICSEARCH_USERNAME; // Replace with your environment variable for username
const validPassword = process.env.ELASTICSEARCH_PASSWORD; // Replace with your environment variable for password

if (username === validUsername && password === validPassword) {
req.session.user = { username: validUsername };
logger.info("User logged in successfully");
res.redirect("dashboard");
} else {
logger.error("Invalid username or password");
res.send("Invalid username or password");
}
});

router.get("/logs/dashboard", (req, res) => {
if (req.session && req.session.user) {
logger.info("User accessed dashboard");
res.redirect("/kibana-dashboard");
} else {
logger.warn("Unauthorized access to dashboard");
res.redirect("/logs");
}
});

// Route to redirect to Kibana dashboard
router.get("/kibana-dashboard", (req, res) => {
// Redirect to Kibana dashboard URL
res.redirect("http://localhost:5601");
});

module.exports = router;
Loading