initial
This commit is contained in:
commit
394ca9fa12
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# docker build --rm -t docker.io/mavenarh/ticket_ai:latest .
|
||||||
|
|
||||||
|
# Use the official Python image as a base
|
||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
#ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
#ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# Set the working directory in the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the dependencies file to the working directory
|
||||||
|
#COPY requirements.txt .
|
||||||
|
|
||||||
|
# Install any dependencies
|
||||||
|
#RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
RUN pip install Flask
|
||||||
|
RUN pip install flask_jwt_extended
|
||||||
|
|
||||||
|
# Copy the content of the local src directory to the working directory
|
||||||
|
COPY src/ .
|
||||||
|
|
||||||
|
# Expose the port the app runs on
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["python", "app.py"]
|
||||||
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
flask:
|
||||||
|
image: ticket_ai docker.io/mavenarh/ticket_ai:latest
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
volumes:
|
||||||
|
- ./src/config.json:/app/config.json
|
||||||
|
- ./logs:/app/logs
|
||||||
73
install.sh
Normal file
73
install.sh
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Update System Packages
|
||||||
|
sudo yum update -y
|
||||||
|
|
||||||
|
# Install Python3 and Pip
|
||||||
|
sudo yum install -y python3 python3-pip
|
||||||
|
|
||||||
|
# Install Flask
|
||||||
|
pip3 install Flask
|
||||||
|
|
||||||
|
# Create a directory for the Flask application
|
||||||
|
mkdir -p ~/flask_app
|
||||||
|
cd ~/flask_app
|
||||||
|
|
||||||
|
# Create the Flask application file (app.py)
|
||||||
|
cat > app.py << 'EOF'
|
||||||
|
from flask import Flask, request, jsonify
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
def read_log(log_file, lines):
|
||||||
|
return subprocess.check_output(['tail', '-n', str(lines), log_file]).decode('utf-8')
|
||||||
|
|
||||||
|
def read_top():
|
||||||
|
return subprocess.check_output(['top', '-b', '-n', '1']).decode('utf-8')
|
||||||
|
|
||||||
|
@app.route('/get_logs', methods=['GET'])
|
||||||
|
def get_logs():
|
||||||
|
issue_type = request.args.get('issue_type')
|
||||||
|
response = {}
|
||||||
|
try:
|
||||||
|
with open('config.json') as config_file:
|
||||||
|
config = json.load(config_file)
|
||||||
|
if issue_type in config:
|
||||||
|
issue_config = config[issue_type]
|
||||||
|
for log in issue_config['logs']:
|
||||||
|
log_output = read_log(log['log_file'], log['lines'])
|
||||||
|
response[log['log_file']] = log_output
|
||||||
|
if issue_config.get('include_top'):
|
||||||
|
response['top'] = read_top()
|
||||||
|
else:
|
||||||
|
response = {"error": "Invalid issue type"}
|
||||||
|
except Exception as e:
|
||||||
|
response = {"error": str(e)}
|
||||||
|
return jsonify(response)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True, host='0.0.0.0')
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create the configuration file (config.json)
|
||||||
|
cat > config.json << 'EOF'
|
||||||
|
{
|
||||||
|
"database_issue": {
|
||||||
|
"include_top": true,
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/var/log/db.log", "lines": 50 },
|
||||||
|
{ "log_file": "/var/log/db_error.log", "lines": 30 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"network_issue": {
|
||||||
|
"include_top": false,
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/var/log/network.log", "lines": 100 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Installation complete. Please modify config.json as needed."
|
||||||
1
logs/error.log
Normal file
1
logs/error.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
this is a error log
|
||||||
45
readme.md
Normal file
45
readme.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# install packages
|
||||||
|
pip install Flask
|
||||||
|
pip install flask_jwt_extended
|
||||||
|
|
||||||
|
# run application
|
||||||
|
python app.py
|
||||||
|
|
||||||
|
# call api
|
||||||
|
http://127.0.0.1:5000/get_logs?issue_type=database_issue
|
||||||
|
|
||||||
|
# sample response
|
||||||
|
{
|
||||||
|
"/var/log/db.log": "Last 50 lines of db.log...",
|
||||||
|
"/var/log/db_error.log": "Last 30 lines of db_error.log...",
|
||||||
|
"top": "Output of the top command..."
|
||||||
|
}
|
||||||
|
|
||||||
|
# run installation script
|
||||||
|
chmod +x install_flask_app.sh
|
||||||
|
./install_flask_app.sh
|
||||||
|
cd ~/flask_app
|
||||||
|
python3 app.py
|
||||||
|
|
||||||
|
# install on centos
|
||||||
|
yum install python36-devel
|
||||||
|
yum install python36-setuptools
|
||||||
|
yum install python36-virtualenv
|
||||||
|
|
||||||
|
python3 -m pip install --upgrade pip
|
||||||
|
|
||||||
|
python3 -m virtualenv env
|
||||||
|
|
||||||
|
pip install Flask
|
||||||
|
pip install flask_jwt_extended
|
||||||
|
|
||||||
|
# usage
|
||||||
|
curl http://127.0.0.1:5000/get_logs?issue_type=Demo
|
||||||
|
|
||||||
|
# run docker image
|
||||||
|
docker run -d \
|
||||||
|
-p 5000:5000 \
|
||||||
|
-v $(pwd)/src/config.json:/app/config.json \
|
||||||
|
-v $(pwd)/logs:/app/logs \
|
||||||
|
--name ticket_ai \
|
||||||
|
docker.io/mavenarh/ticket_ai:latest
|
||||||
12
requirements.txt
Normal file
12
requirements.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
click==8.0.4
|
||||||
|
dataclasses==0.8
|
||||||
|
Flask==2.0.3
|
||||||
|
Flask-JWT-Extended==4.4.2
|
||||||
|
importlib-metadata==4.8.3
|
||||||
|
itsdangerous==2.0.1
|
||||||
|
Jinja2==3.0.3
|
||||||
|
MarkupSafe==2.0.1
|
||||||
|
PyJWT==2.4.0
|
||||||
|
typing_extensions==4.1.1
|
||||||
|
Werkzeug==2.0.3
|
||||||
|
zipp==3.6.0
|
||||||
108
src/app.py
Normal file
108
src/app.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# pip install Flask
|
||||||
|
# pip install flask-jwt-extended
|
||||||
|
|
||||||
|
from flask import Flask, request, jsonify
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
from flask_jwt_extended import JWTManager, create_access_token, jwt_required
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Setup the Flask-JWT-Extended extension
|
||||||
|
app.config["JWT_SECRET_KEY"] = "your-secret-key" # Change this to a random secret key
|
||||||
|
jwt = JWTManager(app)
|
||||||
|
|
||||||
|
# split path to folder and file
|
||||||
|
def split_directory_and_file(path):
|
||||||
|
directory, file_with_wildcard = os.path.split(path)
|
||||||
|
file_name_parts = file_with_wildcard.split('*')
|
||||||
|
file_name = file_name_parts[0] # Get the part before the wildcard
|
||||||
|
return directory, file_name
|
||||||
|
|
||||||
|
# Function to read logs from folder
|
||||||
|
def read_log_from_dir(dir_path, pattern, lines):
|
||||||
|
|
||||||
|
# return variable
|
||||||
|
ret_var = ""
|
||||||
|
|
||||||
|
# Get current time
|
||||||
|
current_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
# Calculate the time 3 hours ago
|
||||||
|
three_hours_ago = current_time - datetime.timedelta(hours=3)
|
||||||
|
|
||||||
|
# List all files in the directory
|
||||||
|
log_files = [file for file in os.listdir(dir_path) if pattern in file]
|
||||||
|
|
||||||
|
# Iterate through log files
|
||||||
|
for file_name in log_files:
|
||||||
|
file_path = os.path.join(dir_path, file_name)
|
||||||
|
|
||||||
|
# Check if file was modified in the last 3 hours
|
||||||
|
modified_time = datetime.datetime.fromtimestamp(os.path.getmtime(file_path))
|
||||||
|
if modified_time > three_hours_ago:
|
||||||
|
ret_var += file_name + "\n"
|
||||||
|
ret_var += subprocess.check_output(['tail', '-n', str(lines), file_path]).decode('utf-8')
|
||||||
|
ret_var += "\n\n"
|
||||||
|
|
||||||
|
return ret_var
|
||||||
|
|
||||||
|
|
||||||
|
# Function to read logs
|
||||||
|
def read_log(log_file, lines):
|
||||||
|
return subprocess.check_output(['tail', '-n', str(lines), log_file]).decode('utf-8')
|
||||||
|
|
||||||
|
# Function to read top
|
||||||
|
def read_top():
|
||||||
|
return subprocess.check_output(['top', '-b', '-n', '1']).decode('utf-8')
|
||||||
|
|
||||||
|
# Login route to authenticate users and return a token
|
||||||
|
@app.route('/login', methods=['POST'])
|
||||||
|
def login():
|
||||||
|
username = request.json.get("username", None)
|
||||||
|
password = request.json.get("password", None)
|
||||||
|
|
||||||
|
# Validate user credentials here (this is just a placeholder logic)
|
||||||
|
if username != "admin" or password != "password":
|
||||||
|
return jsonify({"msg": "Bad username or password"}), 401
|
||||||
|
|
||||||
|
access_token = create_access_token(identity=username)
|
||||||
|
return jsonify(access_token=access_token)
|
||||||
|
|
||||||
|
# Updated get_logs route to require token authentication
|
||||||
|
@app.route('/get_logs', methods=['GET'])
|
||||||
|
# @jwt_required()
|
||||||
|
def get_logs():
|
||||||
|
issue_type = request.args.get("issue_type")
|
||||||
|
response = {}
|
||||||
|
try:
|
||||||
|
with open('config.json') as config_file:
|
||||||
|
config = json.load(config_file)
|
||||||
|
if issue_type in config:
|
||||||
|
issue_config = config[issue_type]
|
||||||
|
|
||||||
|
# logs
|
||||||
|
for log in issue_config['logs']:
|
||||||
|
|
||||||
|
if '*' in log.get('log_file'):
|
||||||
|
directory, file_name = split_directory_and_file(log.get('log_file'))
|
||||||
|
log_output = read_log_from_dir(directory, file_name, log['lines'])
|
||||||
|
else:
|
||||||
|
log_output = read_log(log['log_file'], log['lines'])
|
||||||
|
|
||||||
|
response[log['log_file']] = log_output
|
||||||
|
|
||||||
|
# commands
|
||||||
|
for comm in issue_config['commands']:
|
||||||
|
response[comm.get('tag')] = subprocess.check_output([comm.get('comm')]).decode('utf-8')
|
||||||
|
|
||||||
|
else:
|
||||||
|
response = {"error": "Invalid issue type"}
|
||||||
|
except Exception as e:
|
||||||
|
response = {"error": str(e)}
|
||||||
|
return jsonify(response)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True, host="0.0.0.0")
|
||||||
62
src/config.json
Normal file
62
src/config.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"--Select Issue Type--": {
|
||||||
|
|
||||||
|
"logs": []
|
||||||
|
},
|
||||||
|
"Password Reset Request": {
|
||||||
|
|
||||||
|
"logs": []
|
||||||
|
},
|
||||||
|
"Domain Mapping": {
|
||||||
|
|
||||||
|
"logs": []
|
||||||
|
},
|
||||||
|
"Wallet/Reverse Proxy Required": {
|
||||||
|
|
||||||
|
"logs": []
|
||||||
|
},
|
||||||
|
"Others": {
|
||||||
|
|
||||||
|
"logs": []
|
||||||
|
},
|
||||||
|
"Email Problem": {
|
||||||
|
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/var/log/messages", "lines": 50 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Jasper Reports": {
|
||||||
|
"include_top": true,
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/opt/tomcat/logs/catalina.out", "lines": 50 },
|
||||||
|
{ "log_file": "/var/log/messages", "lines": 50 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Server Unavailable": {
|
||||||
|
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/opt/tomcat/logs/catalina.out", "lines": 50 },
|
||||||
|
{ "log_file": "/opt/oracle/diag/rdbms/xe/XE/trace/alert_XE.log", "lines": 50 },
|
||||||
|
{ "log_file": "/var/log/messages", "lines": 50 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Demo2": {
|
||||||
|
|
||||||
|
"commands": [
|
||||||
|
{ "comm": "top", "tag": "top" }
|
||||||
|
],
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/app/logs/*error_log", "lines": 50 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"Demo": {
|
||||||
|
|
||||||
|
"commands": [
|
||||||
|
],
|
||||||
|
|
||||||
|
"logs": [
|
||||||
|
{ "log_file": "/app/logs/*error_log", "lines": 50 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user