From 27947812380cb4ce0281de9ab3f7237a196e39b4 Mon Sep 17 00:00:00 2001 From: Han Date: Sat, 16 May 2020 10:16:54 +0800 Subject: [PATCH] add files --- cgi/analyst.py | 7 +++ cgi/analyst_2.py | 78 ++++++++++++++++++++++++++++ cgi/analyst_3.py | 92 +++++++++++++++++++++++++++++++++ cgi/analyst_4.py | 91 ++++++++++++++++++++++++++++++++ cgi/check.py | 45 ++++++++++++++++ cgi/foo.png | Bin 0 -> 25271 bytes cgi/foo_1.png | Bin 0 -> 16975 bytes cgi/upload.py | 20 +++++-- cgi/upload_1.py | 69 +++++++++++++++++++++++++ cgi/upload_2.py | 71 +++++++++++++++++++++++++ cgi/upload_3.py | 75 +++++++++++++++++++++++++++ cgi/upload_4.py | 70 +++++++++++++++++++++++++ css/styles_1.css | 23 +++++++++ data/filelist.txt | 1 + index.html | 4 +- index_1.html | 32 ++++++++++++ log_analytics/README.md | 2 + log_analytics/cgi/analyst.py | 53 +++++++++++++++++++ log_analytics/cgi/analyst_1.py | 62 ++++++++++++++++++++++ log_analytics/cgi/upload.py | 43 +++++++++++++++ log_analytics/css/styles.css | 20 +++++++ log_analytics/index.html | 32 ++++++++++++ tmp/log.txt | 11 ++++ 23 files changed, 895 insertions(+), 6 deletions(-) create mode 100644 cgi/analyst_2.py create mode 100644 cgi/analyst_3.py create mode 100644 cgi/analyst_4.py create mode 100644 cgi/check.py create mode 100644 cgi/foo.png create mode 100644 cgi/foo_1.png create mode 100644 cgi/upload_1.py create mode 100644 cgi/upload_2.py create mode 100644 cgi/upload_3.py create mode 100644 cgi/upload_4.py create mode 100644 css/styles_1.css create mode 100644 data/filelist.txt create mode 100644 index_1.html create mode 100644 log_analytics/README.md create mode 100644 log_analytics/cgi/analyst.py create mode 100644 log_analytics/cgi/analyst_1.py create mode 100644 log_analytics/cgi/upload.py create mode 100644 log_analytics/css/styles.css create mode 100644 log_analytics/index.html create mode 100644 tmp/log.txt diff --git a/cgi/analyst.py b/cgi/analyst.py index f4ad283..7fd6841 100644 --- a/cgi/analyst.py +++ b/cgi/analyst.py @@ -4,6 +4,8 @@ from pandas.compat import StringIO import os from pathlib import Path +import subprocess +import re filepath = '/var/www/wou/tmp/' @@ -14,6 +16,11 @@ lastfilename = last_line +cmd_output = subprocess.Popen(['tail', '-n1', '/var/log/apache2/access.log'], stdout=subprocess.PIPE) +out, err = cmd_output.communicate() + +print(out) + file_to_open = filepath + lastfilename.rstrip() f = open(file_to_open, 'r') diff --git a/cgi/analyst_2.py b/cgi/analyst_2.py new file mode 100644 index 0000000..5af6ad8 --- /dev/null +++ b/cgi/analyst_2.py @@ -0,0 +1,78 @@ +#!/usr/bin/python3 + +import pandas as pd +from pandas.compat import StringIO +import os +from pathlib import Path +import subprocess +import re + +filepath = '/var/www/wou/tmp/' + +with open("/var/www/wou/data/filelist.txt", "r") as file: + for last_line in file: + pass + file.close() + +lastfilename = last_line + +rc = subprocess.call('/var/www/wou/cgi/get_info.sh') + +with open("/var/www/wou/data/client_info.txt", "r") as file: + for last_access_line in file: + pass + file.close() + +#r1 = re.findall(r"^[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}\s", last_access_line) + +command_output = os.popen('tail -n1 /var/www/wou/data/client_info.log') +#r1 = re.findall(r"^[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}\s", command_output.read()) +r2 = re.findall(r" [lLwW].{4,11}", command_output.read()) + +file_to_open = filepath + lastfilename.rstrip() + +f = open(file_to_open, 'r') +datainfo = f.readlines(3) + +lines = list(f) +f.close() + +df = pd.read_csv(file_to_open, names=['Time','Severity','Text'], engine='python') +df.to_html('../output.html', justify='center') + +print("Content-Type: text/html\n") +print("\n") +print("""\ + + + + Data Analytic Output + + + + +""") +print("\n") +print("

You are using a {} system

".format(r2)) +print("\n") +print("

Returns of your data filename: {}

".format(lastfilename)) +print("""\ + + + +""".format(lastfilename)) + +print("""\ + +
+ +
+ +
+ + +
+ + + +""") diff --git a/cgi/analyst_3.py b/cgi/analyst_3.py new file mode 100644 index 0000000..cd6a040 --- /dev/null +++ b/cgi/analyst_3.py @@ -0,0 +1,92 @@ +#!/usr/bin/python3 + +import pandas as pd +from pandas.compat import StringIO +import os +from pathlib import Path +import subprocess +import re +import matplotlib.pyplot as plt + +filepath = '/var/www/wou/tmp/' + +with open("/var/www/wou/data/filelist.txt", "r") as file: + for last_line in file: + pass + file.close() + +lastfilename = last_line + +rc = subprocess.call('/var/www/wou/cgi/get_info.sh') + +with open("/var/www/wou/data/client_info.txt", "r") as file: + for last_access_line in file: + pass + file.close() + +#r1 = re.findall(r"^[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}\s", last_access_line) + +command_output = os.popen('tail -n1 /var/www/wou/data/client_info.log') +#r1 = re.findall(r"^[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}\s", command_output.read()) + +r2 = re.findall(r" [lLwW][iI][nN].{4,11} ", command_output.read()) + +file_to_open = filepath + lastfilename.rstrip() + +f = open(file_to_open, 'r') +datainfo = f.readlines(3) + +lines = list(f) +f.close() + +Data = {'Tasks': [300,500,700]} +df = DataFrame(Data,columns=['Tasks'],index = ['Tasks Pending','Tasks Ongoing','Tasks Completed']) + +df.plot.pie(y='Tasks',figsize=(5, 5),autopct='%1.1f%%', startangle=90) + +plt.savefig('foo.png') + +df = pd.read_csv(file_to_open, names=['Time','Severity','Text'], engine='python') +df['Severity'].value_counts() + +df.plot.pie(y='Severity',figsize=(10,10),autopct='%1.1f%%', startangle=90) +plt.savefig('../foo.png') + +df.to_html('../output.html', justify='center') + +print("Content-Type: text/html\n") +print("\n") +print("""\ + + + + Data Analytic Output + + + + +""") +print("\n") +print("

You are using a {} system

".format(r2)) +print("\n") +print("

Returns of your data filename: {}

".format(lastfilename)) +print("""\ + + + +""".format(lastfilename)) + +print("""\ + +
+ +
+ +
+ + +
+ + + +""") diff --git a/cgi/analyst_4.py b/cgi/analyst_4.py new file mode 100644 index 0000000..4b3b357 --- /dev/null +++ b/cgi/analyst_4.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 + +import pandas as pd +from pandas.compat import StringIO +import os +from pathlib import Path +import subprocess +import re +import matplotlib + +matplotlib.use('Agg') + +import matplotlib.pyplot as plt + + +filepath = '/var/www/wou/tmp/' + +with open("/var/www/wou/data/filelist.txt", "r") as file: + for last_line in file: + pass + file.close() + +lastfilename = last_line + +rc = subprocess.call('/var/www/wou/cgi/get_info.sh') + +with open("/var/www/wou/data/client_info.txt", "r") as file: + for last_access_line in file: + pass + file.close() + +command_output = os.popen('tail -n1 /var/www/wou/data/client_info.log') + +r2 = re.findall(r" [lLwW][iI][nN].{4,11} ", command_output.read()) + +file_to_open = filepath + lastfilename.rstrip() + +f = open(file_to_open, 'r') +datainfo = f.readlines(3) + +lines = list(f) +f.close() + +df = pd.read_csv(file_to_open, names=['Time','Severity','Text'], engine='python') + +df.to_html('../output.html', justify='center') + +df.Severity.value_counts().plot.pie(y='Severities', figsize=(5, 5),autopct='%1.1f%%', startangle=90) +plt.savefig('../images/chart_output.png') + + +print("Content-Type: text/html\n") +print("\n") +print("""\ + + + + Data Analytic Output + + + + +""") +print("\n") +print("

You are using a {} system

".format(r2)) +print("\n") +print("

Returns of your data filename: {}

".format(lastfilename)) +print("""\ + + + +""".format(lastfilename)) + +print("""\ + +
+ +
+ +
+ +
+ +
+ + +
+ + + +""") diff --git a/cgi/check.py b/cgi/check.py new file mode 100644 index 0000000..9e10a57 --- /dev/null +++ b/cgi/check.py @@ -0,0 +1,45 @@ +from pandas import DataFrame + +import matplotlib + +matplotlib.use('Agg') + +import matplotlib.pyplot as plt +import pandas as pd + +# Data = {'Tasks': [300,500,700]} +# df = DataFrame(Data,columns=['Tasks'],index = ['Tasks Pending','Tasks Ongoing','Tasks Completed']) + +sevs = {} + +df = pd.read_csv('../tmp/log.txt', names=['Time','Severity','Text'], engine='python') + +print(df) + +sd = df['Severity'] + +cf = pd.value_counts(df['Severity'].values) + + +print(cf) + + +df.Severity.value_counts().plot.pie(y='Severities', figsize=(5, 5),autopct='%1.1f%%', startangle=90) +plt.savefig('foo_1.png') + +#print(sd) +# plt.title('severities dataset') +# plt.axis('severities') + + + +# df.plot.pie(y='Severity') + +# plt.show() + + +#sd.plot.pie(y='Severity',figsize=(5, 5),autopct='%1.1f%%', startangle=90) + +# # df.plot.pie(y='Tasks',figsize=(5, 5),autopct='%1.1f%%', startangle=90) +# # #plt.show() +# plt.savefig('foo_1.png') \ No newline at end of file diff --git a/cgi/foo.png b/cgi/foo.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e24cde762096e83f58ca9e7a0e11b29b41d0b8 GIT binary patch literal 25271 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 F_#fff>2?4B literal 0 HcmV?d00001 diff --git a/cgi/foo_1.png b/cgi/foo_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5fca00173cc5acbe1539ec2a0e4fb6d2c373547b GIT binary patch literal 16975 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 literal 0 HcmV?d00001 diff --git a/cgi/upload.py b/cgi/upload.py index 8c0301e..0a719b0 100644 --- a/cgi/upload.py +++ b/cgi/upload.py @@ -2,6 +2,7 @@ import cgi, os import cgitb; cgitb.enable() +import webbrowser form = cgi.FieldStorage() @@ -20,14 +21,27 @@ ap_file.close() message = 'The file "' + fn + '" was uploaded successfully' - + +elif not (fn == ('.txt') or ('.log') or ('.csv')): + message = 'uploaded file type is not supported' + else: message = 'No file was uploaded' + +with open("/var/log/apache2/access.log", "r") as file: + for last_access_line in file: + pass + file.close() + + print """\ Content-Type: text/html\n + + +

%s

@@ -36,8 +50,8 @@
-Back To Main Page -""" % (message,) +""" % (message,) \ No newline at end of file diff --git a/cgi/upload_1.py b/cgi/upload_1.py new file mode 100644 index 0000000..369ebff --- /dev/null +++ b/cgi/upload_1.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +import cgi, os +import cgitb; cgitb.enable() +import webbrowser + +form = cgi.FieldStorage() + +# Get filename here. +fileitem = form['filename'] + +# Test if the file was uploaded + +if fileitem.filename: + # strip leading path from file name to avoid + # directory traversal attacks + fn = os.path.basename(fileitem.filename.replace("\\", "/" )) + + if not (fn.split('.')[1] == 'txt' or fn.endswith == 'log' or fn.endswith == 'csv'): + message = 'uploaded file type is not supported' + + print """\ + Content-Type: text/html\n + + +

%s

+ + + + """ % (message,) + + else: + open('/var/www/wou/tmp/' + fn, 'wb').write(fileitem.file.read()) + + ap_file = open('/var/www/wou/data/filelist.txt', 'a') + ap_file.write(fn + "\n") + ap_file.close() + + message = 'The file "' + fn + '" was uploaded successfully' + + print """\ + Content-Type: text/html\n + + +

%s

+
+
+ +
+
+ + + """ % (message,) + +else: + message = 'No file was uploaded' + +print """\ + Content-Type: text/html\n + + +

%s

+ + + + """ % (message,) diff --git a/cgi/upload_2.py b/cgi/upload_2.py new file mode 100644 index 0000000..998f077 --- /dev/null +++ b/cgi/upload_2.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + +import cgi, os +import cgitb; cgitb.enable() +import webbrowser + +form = cgi.FieldStorage() + +# Get filename here. +fileitem = form['filename'] + +# Test if the file was uploaded + +if fileitem.filename: + # strip leading path from file name to avoid + # directory traversal attacks + fn = os.path.basename(fileitem.filename.replace("\\", "/" )) + + # check for supported file type + if not (fn.split('.')[1] == 'txt' or fn.endswith == 'log' or fn.endswith == 'csv'): + message = 'uploaded file type is not supported' + + print """\ + Content-Type: text/html\n + + +

%s

+ + + + + """ % (message,) + + else: + open('/var/www/wou/tmp/' + fn, 'wb').write(fileitem.file.read()) + + ap_file = open('/var/www/wou/data/filelist.txt', 'a') + ap_file.write(fn + "\n") + ap_file.close() + + message = 'The file "' + fn + '" was uploaded successfully' + + print """\ + Content-Type: text/html\n + + +

%s

+ +
+
+ +
+
+ + + + """ % (message,) + +else: + message = 'No file was uploaded' + + print """\ + Content-Type: text/html\n + + +

%s

+ + + + + """ % (message,) diff --git a/cgi/upload_3.py b/cgi/upload_3.py new file mode 100644 index 0000000..7450f05 --- /dev/null +++ b/cgi/upload_3.py @@ -0,0 +1,75 @@ +#!/usr/bin/python + +import cgi, os +import cgitb; cgitb.enable() + +form = cgi.FieldStorage() + +# Get filename here. +fileitem = form['filename'] + +# Test if the file was uploaded + +if fileitem.filename: + # strip leading path from file name to avoid + # directory traversal attacks + fn = os.path.basename(fileitem.filename.replace("\\", "/" )) + + # check for supported file type + if not (fn.split('.')[1] == 'txt' or fn.endswith == 'log' or fn.endswith == 'csv'): + message = 'uploaded file type is not supported' + + print """\ +Content-Type: text/html\n + + +

%s

+ + + + + """ % (message,) + + exit() + + # open file directory and upload file + open('/var/www/wou/tmp/' + fn, 'wb').write(fileitem.file.read()) + + # store filename in filelist + ap_file = open('/var/www/wou/data/filelist.txt', 'a') + ap_file.write(fn + "\n") + ap_file.close() + + message = 'The file ' + fn + ' was uploaded successfully' + + print """\ +Content-Type: text/html\n + + +

%s

+ +
+
+ +
+
+ + + + """ % (message,) + +else: + + # no file submitted + message = 'No file was uploaded' + + print """\ +Content-Type: text/html\n + + +

%s

+ + + + + """ % (message,) diff --git a/cgi/upload_4.py b/cgi/upload_4.py new file mode 100644 index 0000000..1797cad --- /dev/null +++ b/cgi/upload_4.py @@ -0,0 +1,70 @@ +#!/usr/bin/python + +import cgi, os +import cgitb; cgitb.enable() + +form = cgi.FieldStorage() + +# Get filename here. +fileitem = form['filename'] + +# Test if the file was uploaded + +if fileitem.filename: + # strip leading path from file name to avoid + # directory traversal attacks + fn = os.path.basename(fileitem.filename.replace("\\", "/" )) + + if not (fn.split('.')[1] == 'txt' or fn.endswith == 'log' or fn.endswith == 'csv'): + message = 'uploaded file type is not supported' + + print """\ +Content-Type: text/html\n + + +

%s

+ + + + + """ % (message,) + + exit() + + open('/var/www/wou/tmp/' + fn, 'wb').write(fileitem.file.read()) + + ap_file = open('/var/www/wou/data/filelist.txt', 'a') + ap_file.write(fn + "\n") + ap_file.close() + + message = 'The file ' + fn + ' was uploaded successfully' + + print """\ +Content-Type: text/html\n + + +

%s

+ +
+
+ +
+
+ + + + """ % (message,) + +else: + message = 'No file was uploaded' + + print """\ +Content-Type: text/html\n + + +

%s

+ + + + + """ % (message,) diff --git a/css/styles_1.css b/css/styles_1.css new file mode 100644 index 0000000..072442c --- /dev/null +++ b/css/styles_1.css @@ -0,0 +1,23 @@ +.div_1 { + position: relative; + width: 400px; + heigh: 200px; +} + +form { + position: absolute; + top: 0; +} + +.box-1 { + position: static; +} + +.box-2 { + position: relative; + left: 10px; +} +img { + position: relative; +} + diff --git a/data/filelist.txt b/data/filelist.txt new file mode 100644 index 0000000..008a58e --- /dev/null +++ b/data/filelist.txt @@ -0,0 +1 @@ +data_info_v2.txt \ No newline at end of file diff --git a/index.html b/index.html index e229de9..a58f926 100644 --- a/index.html +++ b/index.html @@ -18,7 +18,6 @@

Log File Upload

Please upload log file for data analysis

-
@@ -28,5 +27,4 @@

Log File Upload

- - + \ No newline at end of file diff --git a/index_1.html b/index_1.html new file mode 100644 index 0000000..e229de9 --- /dev/null +++ b/index_1.html @@ -0,0 +1,32 @@ + + + + + + + Data Analytic Site + + + + + + + + + +

Log File Upload

+ +

Please upload log file for data analysis

+ + +
+ + + + +
+ + + + + diff --git a/log_analytics/README.md b/log_analytics/README.md new file mode 100644 index 0000000..c17ef85 --- /dev/null +++ b/log_analytics/README.md @@ -0,0 +1,2 @@ +# log_analytics +syslog analytic tool diff --git a/log_analytics/cgi/analyst.py b/log_analytics/cgi/analyst.py new file mode 100644 index 0000000..aa33b26 --- /dev/null +++ b/log_analytics/cgi/analyst.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 + +import pandas as pd +from pandas.compat import StringIO +import os +from pathlib import Path + +filepath = '/var/www/wou/tmp/' + +with open("/var/www/wou/data/filelist.txt", "r") as file: + for last_line in file: + pass + file.close() + +lastfilename = last_line + +file_to_open = filepath + lastfilename.rstrip() + +f = open(file_to_open, 'r') +datainfo = f.read() +f.close() + +df = pd.read_csv(file_to_open, names=['Time','Severity','Text'], engine='python') +df.to_html('../output.html', justify='center') + +print("Content-Type: text/html\n") +print("\n") +print("""\ + + + + Data Analytic Output + + + + +""") +print("\n") +print("\n") +print("""\ + +
+ +
+ +
+ + +
+ + + +""") diff --git a/log_analytics/cgi/analyst_1.py b/log_analytics/cgi/analyst_1.py new file mode 100644 index 0000000..589e39b --- /dev/null +++ b/log_analytics/cgi/analyst_1.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 + +import pandas as pd +from pandas.compat import StringIO +import os +from pathlib import Path + +filepath = '/var/www/wou/tmp/' + +with open("/var/www/wou/data/filelist.txt", "r") as file: + for last_line in file: + pass + file.close() + +lastfilename = last_line + +file_to_open = filepath + lastfilename.rstrip() + +f = open(file_to_open, 'r') +datainfo = f.readlines(3) + +lines = list(f) +f.close() + +df = pd.read_csv(file_to_open, names=['Time','Severity','Text'], engine='python') +df.to_html('../output.html', justify='center') + +print("Content-Type: text/html\n") +print("\n") +print("""\ + + + + Data Analytic Output + + + + +""") +print("\n") +print("\n") +print("

Returns of your data filename: {}

".format(lastfilename)) +print("""\ + + + +""".format(lastfilename)) + +print("""\ + +
+ +
+ +
+ + +
+ + + +""") diff --git a/log_analytics/cgi/upload.py b/log_analytics/cgi/upload.py new file mode 100644 index 0000000..d0d18cf --- /dev/null +++ b/log_analytics/cgi/upload.py @@ -0,0 +1,43 @@ +#!/usr/bin/python + +import cgi, os +import cgitb; cgitb.enable() + +form = cgi.FieldStorage() + +# Get filename here. +fileitem = form['filename'] + +# Test if the file was uploaded +if fileitem.filename: + # strip leading path from file name to avoid + # directory traversal attacks + fn = os.path.basename(fileitem.filename.replace("\\", "/" )) + open('/var/www/wou/tmp/' + fn, 'wb').write(fileitem.file.read()) + + ap_file = open('/var/www/wou/data/filelist.txt', 'a') + ap_file.write(fn + "\n") + ap_file.close() + + message = 'The file "' + fn + '" was uploaded successfully' + +else: + message = 'No file was uploaded' + +print """\ +Content-Type: text/html\n + + +

%s

+ +
+
+ +
+
+ + + +""" % (message,) diff --git a/log_analytics/css/styles.css b/log_analytics/css/styles.css new file mode 100644 index 0000000..e112de8 --- /dev/null +++ b/log_analytics/css/styles.css @@ -0,0 +1,20 @@ +.div_1 { + position: relative; + width: 400px; + heigh: 200px; +} + +form { + position: absolute; + top: 0; +} + +.box-1 { + position: static; +} + +.box-2 { + position: relative; + top: 1200px; + left: 30px; +} diff --git a/log_analytics/index.html b/log_analytics/index.html new file mode 100644 index 0000000..42a1fd9 --- /dev/null +++ b/log_analytics/index.html @@ -0,0 +1,32 @@ + + + + + + + Data Analytic Site + + + + + + + + + +

Log File Upload

+ +

Please upload log file for data analysis

+ + +
+
+ + +
+
+ + + + + diff --git a/tmp/log.txt b/tmp/log.txt new file mode 100644 index 0000000..0b5e83d --- /dev/null +++ b/tmp/log.txt @@ -0,0 +1,11 @@ +Nov 1 2019 23:56:27, INFO, "kernel:Initializing cgroup subsys cpuset" +Nov 1 2019 23:56:28, INFO, "kernel:Initializing cgroup subsys cpu" +Nov 1 2019 23:56:29, WARN, "kernel:Initializing cgroup subsys cpuacct" +Nov 1 2019 23:33:57, INFO, kernel:initializing cgroup subsys cpuset +Nov 1 2019 23:34:57, INFO, kernel:initializing cgroup subsys cpuset +Nov 1 2019 22:35:57, INFO, kernel:initializing cgroup subsys cpuset +Nov 1 2019 22:36:57, WARN, kernel:initializing cgroup subsys cpuset +Nov 1 2019 22:37:57, INFO, kernel:initializing cgroup subsys cpuset +Nov 1 2019 22:38:57, ERR, kernel:initializing cgroup subsys cpuset +Nov 1 2019 22:39:57, INFO, kernel:initializing cgroup subsys cpuset +Nov 1 2019 22:40:57, INFO, kernel:initializing cgroup subsys cpuset \ No newline at end of file