From 394ca9fa120fdfb5e72ac3e189bbbcbf32e5506a Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 21 Feb 2024 19:59:37 +0500 Subject: [PATCH] initial --- Dockerfile | 29 ++++++++++++ docker-compose.yml | 10 +++++ install.sh | 73 ++++++++++++++++++++++++++++++ logs/error.log | 1 + readme.md | 45 +++++++++++++++++++ requirements.txt | 12 +++++ src/app.py | 108 +++++++++++++++++++++++++++++++++++++++++++++ src/config.json | 62 ++++++++++++++++++++++++++ 8 files changed, 340 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 install.sh create mode 100644 logs/error.log create mode 100644 readme.md create mode 100644 requirements.txt create mode 100644 src/app.py create mode 100644 src/config.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c3a0681 --- /dev/null +++ b/Dockerfile @@ -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"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a388a62 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..cb818c4 --- /dev/null +++ b/install.sh @@ -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." diff --git a/logs/error.log b/logs/error.log new file mode 100644 index 0000000..dec0b63 --- /dev/null +++ b/logs/error.log @@ -0,0 +1 @@ +this is a error log \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..96ab048 --- /dev/null +++ b/readme.md @@ -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 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6ff241a --- /dev/null +++ b/requirements.txt @@ -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 diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..175c9bc --- /dev/null +++ b/src/app.py @@ -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") diff --git a/src/config.json b/src/config.json new file mode 100644 index 0000000..a3d9c75 --- /dev/null +++ b/src/config.json @@ -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 } + ] + } +}