#wip: Bash done. Python base done. Building SQL Server base.
This commit is contained in:
parent
53662c1b38
commit
c178dbd9b2
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/Data
|
||||
/Public/data
|
||||
__pycache__
|
||||
*.[Ss]ecrets.*
|
||||
*.[Ss]ecret.*
|
||||
/Python/pyodbc.py
|
||||
2
Bash/NucelarMonitor.debian.execute.sh
Executable file
2
Bash/NucelarMonitor.debian.execute.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
nohup ./tu_script.sh > /dev/null 2>&1 &
|
||||
160
Bash/NucelarMonitor.debian.script.sh
Executable file
160
Bash/NucelarMonitor.debian.script.sh
Executable file
@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Settings.
|
||||
key="kyman_9750h"
|
||||
candle_seconds=10
|
||||
candle_sleep_seconds=1
|
||||
execute_sleep_seconds=0
|
||||
show_json=true
|
||||
send_json=true
|
||||
url_server="http://192.168.1.131:13000/debian"
|
||||
# Settings.
|
||||
|
||||
function get_net_data(){
|
||||
echo $(cat /proc/net/dev|tail -n +3|awk '{
|
||||
|
||||
interface = $1;
|
||||
|
||||
gsub(/:/, "", interface);
|
||||
array = "[\"" interface "\"," $2 "," $3 "," $4 "," $10 "," $11 "," $12 "]";
|
||||
|
||||
json = json == "" ? array : json "," array;
|
||||
|
||||
}END{
|
||||
print "[" json "]";
|
||||
}')
|
||||
}
|
||||
|
||||
function execute(){
|
||||
|
||||
local domain=$(hostname -d)
|
||||
local ips=$(ip -o addr|awk '{
|
||||
|
||||
is_ipv6 = $3 == "inet6" ? "true" : "false";
|
||||
|
||||
split($1, i, ":");
|
||||
split($4, ip, "/");
|
||||
|
||||
array = "[" i[1] ",\"" $2 "\"," is_ipv6 ",\"" ip[1] "\"," ip[2] "]";
|
||||
json = json == "" ? array : json "," array;
|
||||
|
||||
}END{
|
||||
print "[" json "]";
|
||||
}')
|
||||
local hostnames=$(hostname -A|awk '{
|
||||
json = json == "" ? "\"" $1 "\"" : json ",\"" $1 "\"";
|
||||
}END{
|
||||
print "[" json "]";
|
||||
}')
|
||||
local disks=$(lsblk -b -n -o name,size,fsavail,mountpoint|grep -E '└─|├─'|awk '{
|
||||
|
||||
device = $1;
|
||||
total = $2;
|
||||
available = $3 ~ /^\// || $3 == "" ? 0 : $3;
|
||||
mountpoint = $4 != "" ? "\"" $4 "\"" : $3 ~ /^\// ? "null" : "\"" $3 "\"";
|
||||
|
||||
gsub(/├─|└─/, "", device);
|
||||
array = "[\"" device "\"," total "," available "," mountpoint "]";
|
||||
|
||||
json = json == "" ? array : json "," array;
|
||||
|
||||
}END{
|
||||
print "[" json "]";
|
||||
}')
|
||||
local iterations=0
|
||||
local cpu_in=
|
||||
local cpu_out=
|
||||
local cpu_minimum=
|
||||
local cpu_maximum=
|
||||
local cpu_average=0
|
||||
local memory_in=
|
||||
local memory_out=
|
||||
local memory_minimum=
|
||||
local memory_maximum=
|
||||
local memory_average=0
|
||||
local memory_total=$(cat /proc/meminfo|grep MemTotal:|awk '{print $2 * 1024}')
|
||||
local limit_seconds=$(($(date +%s) + $candle_seconds))
|
||||
local json="["
|
||||
local net_data="["
|
||||
local candle_start=$(date +%s)
|
||||
local candle_end=
|
||||
|
||||
net_data=$net_data$(get_net_data)
|
||||
|
||||
while true; do
|
||||
|
||||
cpu=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}')
|
||||
# memory=$(cat /proc/meminfo|grep MemFree:|awk '{print $2 * 1024}')
|
||||
memory=$(cat /proc/meminfo|grep MemAvailable:|awk '{print $2 * 1024}')
|
||||
|
||||
# cpu_average=$((cpu_average + cpu))
|
||||
# memory_average=$((memory_average + memory))
|
||||
cpu_average=$(echo "$cpu_average + $cpu"|bc -l)
|
||||
memory_average=$(echo "$memory_average + $memory"|bc -l)
|
||||
|
||||
cpu=${cpu/,/.}
|
||||
|
||||
cpu_out=$cpu
|
||||
memory_out=$memory
|
||||
iterations=$((iterations + 1))
|
||||
|
||||
if [ -z "$cpu_in" ]; then
|
||||
cpu_in=$cpu
|
||||
memory_in=$memory
|
||||
cpu_minimum=$cpu
|
||||
cpu_maximum=$cpu
|
||||
memory_minimum=$memory
|
||||
memory_maximum=$memory
|
||||
else
|
||||
|
||||
if [ "$(echo "$cpu < $cpu_minimum"|bc -l)" -eq 1 ];then cpu_minimum=$cpu;fi
|
||||
if [ "$(echo "$cpu > $cpu_maximum"|bc -l)" -eq 1 ];then cpu_maximum=$cpu;fi
|
||||
if [ "$(echo "$memory < $memory_minimum"|bc -l)" -eq 1 ];then memory_minimum=$memory;fi
|
||||
if [ "$(echo "$memory > $memory_maximum"|bc -l)" -eq 1 ];then memory_maximum=$memory;fi
|
||||
# cpu_minimum=$(echo -e "$cpu_minimum\n$cpu" | sort -n | head -1)
|
||||
# cpu_maximum=$(echo -e "$cpu_maximum\n$cpu" | sort -n | tail -1)
|
||||
# memory_minimum=$(echo -e "$memory_minimum\n$memory" | sort -n | head -1)
|
||||
# memory_maximum=$(echo -e "$memory_maximum\n$memory" | sort -n | tail -1)
|
||||
|
||||
if [ $(date +%s) -ge $limit_seconds ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$domain" ]; then
|
||||
domain="null"
|
||||
else
|
||||
domain="\"$domain\""
|
||||
fi
|
||||
|
||||
# cpu_average=$((cpu_average / iterations))
|
||||
# memory_average=$((memory_average / iterations))
|
||||
cpu_average=$(echo "scale=6; $cpu_average / $iterations"|bc|awk '{printf $1 + 0}')
|
||||
memory_average=$(echo "scale=6; $memory_average / $iterations"|bc|awk '{printf $1 + 0}')
|
||||
|
||||
net_data="$net_data,$(get_net_data)]"
|
||||
candle_end=$(date +%s)
|
||||
|
||||
json="$json$hostnames,$domain,$ips,$disks,$iterations"
|
||||
json="$json,[$candle_start,$candle_end]"
|
||||
json="$json,[${cpu_in//,/.},${cpu_out//,/.},${cpu_minimum//,/.},${cpu_maximum//,/.},$cpu_average]"
|
||||
json="$json,[$memory_total,$memory_in,$memory_out,$memory_minimum,$memory_maximum,$memory_average]"
|
||||
json="$json,$net_data"
|
||||
json="$json]"
|
||||
|
||||
if [ "$show_json" = true ]; then echo "$json";fi
|
||||
if [ "$send_json" = true ]; then
|
||||
local response=$(echo "$json"|curl -s -X POST -H "Content-Type: application/json" -d @- "$url_server/$key")
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
while true; do
|
||||
execute
|
||||
if [ $execute_sleep_seconds -gt 0 ]; then
|
||||
sleep $execute_sleep_seconds
|
||||
fi
|
||||
done
|
||||
1
Public/index.html
Normal file
1
Public/index.html
Normal file
@ -0,0 +1 @@
|
||||
<h1>Funca</h1>
|
||||
738
Python/NucelarMonitor.py
Normal file
738
Python/NucelarMonitor.py
Normal file
@ -0,0 +1,738 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
from typing import Any, Optional, Sequence, Self, Callable
|
||||
from re import compile as re_compile, Pattern as REPattern, Match as REMatch, IGNORECASE as RE_IGNORE_CASE
|
||||
from pyodbc import connect as pyodbc_connect
|
||||
from socket import socket as Socket, AF_INET as ADDRESS_FAMILY_IPV4, SOCK_STREAM as SOCKET_STREAM, SOL_SOCKET as SOCKET_LAYER, SO_REUSEADDR as SOCKET_REUSE_ADDRESS
|
||||
from inspect import stack as get_stack, FrameInfo
|
||||
from traceback import format_stack as trace_format_stack, extract_tb as extract_traceback
|
||||
from threading import Thread
|
||||
from os.path import exists as path_exists, dirname as directory_name, abspath as absolute_path
|
||||
from json import loads as json_decode, dumps as json_encode
|
||||
from mimetypes import guess_type as get_mime_by_extension
|
||||
|
||||
class NucelarMonitor:
|
||||
|
||||
DEFAULT_SETTINGS:dict[str, Any|None] = {
|
||||
"autostart" : True,
|
||||
"print_format" : "[{type}] {yyyy}{mm}{dd} {hh}{ii}{ss} [{line}]{file}({method}): {message}",
|
||||
"exception_format" : " '[{line}]{file}({method})'{lines}\n\n{exception_message}",
|
||||
"print_types" : [
|
||||
["unkn", "unknown"],
|
||||
["info", "information"],
|
||||
["warn", "warning"],
|
||||
["erro", "error", "wrong", "failure", "fail", "no"],
|
||||
["exce", "exception", "except"],
|
||||
[" ok ", "ok", "success", "succeed", "yes"],
|
||||
["test", "debug"]
|
||||
],
|
||||
"http_host" : "0.0.0.0",
|
||||
"http_port" : 13000,
|
||||
"http_cache_size" : 1024,
|
||||
"http_maximum_connections" : 5,
|
||||
"http_header_response" : (
|
||||
"{http_protocol}/{http_version} {http_code} {http_message}\r\n" +
|
||||
"Content-Type: {mime}\r\n" +
|
||||
"Content-Length: {length}\r\n" +
|
||||
"\r\n"
|
||||
),
|
||||
"http_protocol" : "HTTP",
|
||||
"http_version" : "1.1",
|
||||
"http_code" : 200,
|
||||
"http_message" : "OK",
|
||||
"http_encoder" : "utf-8",
|
||||
"index_files" : ("index.html", "index.htm"),
|
||||
"sql_host" : "127.0.0.1",
|
||||
"sql_port" : 1433,
|
||||
"sql_user" : "sa",
|
||||
"sql_password" : "password",
|
||||
"sql_database" : "NucelarMonitor",
|
||||
"default_controllers" : {
|
||||
"get" : {
|
||||
"/" : "/Public"
|
||||
},
|
||||
"post" : {
|
||||
"/debian/{key}" : "debian"
|
||||
}
|
||||
},
|
||||
"default_connections" : {}
|
||||
}
|
||||
DEFAULT_I18N:dict[str, dict[str, str|Sequence[str]]] = {
|
||||
"english" : {}
|
||||
}
|
||||
ROOT:str = directory_name(absolute_path(__file__))
|
||||
SLASH:str = "/" if "/" in ROOT else "\\\\"
|
||||
SPECIAL_REGULAR_EXPRESSION_CHARACTERS:dict[str, str] = {
|
||||
"\r" : "r",
|
||||
"\n" : "n",
|
||||
"\t" : "t"
|
||||
}
|
||||
|
||||
RE_KEY:REPattern = re_compile(r'^[a-z_][a-z0-9_]*$', RE_IGNORE_CASE)
|
||||
RE_STRING_VARIABLE:REPattern = re_compile(r'\{([a-z_][a-z0-9_]*)\}', RE_IGNORE_CASE)
|
||||
RE_EXCEPTION:REPattern = re_compile(r'^\s*File "([^"]+)", line ([0-9]+), in ([^\n]+)(.*|[\r\n]*)*$')
|
||||
RE_NEW_LINE:REPattern = re_compile(r'\r\n|[\r\n]')
|
||||
RE_TO_SNAKE:REPattern = re_compile(r'[^a-zA-Z0-9]*([A-Z][A-Z0-9]*)|[^a-z0-9]+')
|
||||
RE_HTTP_REQUEST:REPattern = re_compile(r'^([^\s]+)\s([^\s\?\#]+)(?:\?([^#]+))?(?:\#[^\s]+)?\s([^\/]+)\/([0-9\.]+)$')
|
||||
RE_HEADER_LINE:REPattern = re_compile(r'^([^\:]+)\:(.+)$')
|
||||
RE_HTTP_BLOCKS:REPattern = re_compile(r'((?:(?!(?:(?:\r\n){2}|\n{2}|\r{2}))(?:.|[\r\n]+))+)(?:(?:(?:\r\n){2}|\n{2}|\r{2})((?:.+|[\r\n]+)*))?')
|
||||
RE_LAST_DIRECTORY:REPattern = re_compile(r'^(.*)[\/][^\/]*\/?$')
|
||||
RE_SLASHES:REPattern = re_compile(r'[\\\/]+')
|
||||
RE_TO_REGULAR_EXPRESSION:REPattern = re_compile(r'[\(\)\{\}\/\\\.\-\+\*\^\$\?\|\!\<\>\r\n\t]')
|
||||
RE_ROUTE_KEY:REPattern = re_compile(r'\\\{([a-z_][a-z0-9_]*)\\\}', RE_IGNORE_CASE)
|
||||
|
||||
class Request:
|
||||
|
||||
def __init__(self:Self, data:bytes, encoder:str = "utf-8") -> None:
|
||||
|
||||
self.method:str
|
||||
self.request:str
|
||||
self.value_get:str|None
|
||||
self.variables_get:dict[str, str]
|
||||
self.variables_post:dict[str, str]
|
||||
self.protocol:str
|
||||
self.protocol_version:str
|
||||
self.body:str
|
||||
self.variables_uri:dict[str, str] = {}
|
||||
|
||||
header, body = (lambda header, body:(
|
||||
NucelarMonitor.RE_NEW_LINE.split(str(header).strip()), body
|
||||
))(*NucelarMonitor.RE_HTTP_BLOCKS.match(data.decode(encoder)).groups())
|
||||
|
||||
(
|
||||
self.method,
|
||||
self.request,
|
||||
self.value_get,
|
||||
self.variables_get,
|
||||
self.protocol,
|
||||
self.protocol_version
|
||||
) = (lambda method, request, variables, protocol, protocol_version:(
|
||||
str(method).lower(),
|
||||
request,
|
||||
variables,
|
||||
self.parse_variables(variables),
|
||||
protocol,
|
||||
protocol_version
|
||||
))(*NucelarMonitor.RE_HTTP_REQUEST.match(header[0]).groups())
|
||||
self.body = body
|
||||
self.variables_post = self.parse_variables(body)
|
||||
|
||||
def set_uri_variables(self:Self, keys:list[str], matches:REMatch) -> None:
|
||||
|
||||
i:int
|
||||
value:str
|
||||
|
||||
for i, value in enumerate(matches.groups()):
|
||||
self.variables_uri[keys[i]] = value
|
||||
|
||||
def get(self:Self, keys:str|Sequence[str], default:Optional[Any] = None) -> Any|None:
|
||||
return NucelarMonitor.get_value(keys, (
|
||||
self.variables_uri, self.variables_get, self.variables_post
|
||||
), default)
|
||||
|
||||
@classmethod
|
||||
def parse_variables(cls:type[Self], string:Optional[str]) -> dict[str, str]:
|
||||
if not string:
|
||||
return {}
|
||||
|
||||
variables:dict[str, str] = {}
|
||||
pair:str
|
||||
|
||||
for pair in string.split("&"):
|
||||
if "=" in pair:
|
||||
key, value = pair.split("=", 1)
|
||||
variables[cls.to_snake(key)] = value
|
||||
else:
|
||||
variables[cls.to_snake(pair)] = ""
|
||||
|
||||
return variables
|
||||
|
||||
@staticmethod
|
||||
def to_snake(string:str) -> str:
|
||||
|
||||
def callback(matches:REMatch) -> str:
|
||||
|
||||
upper:str|None = matches.group(1)
|
||||
|
||||
return "_" + upper.lower() if upper else "_"
|
||||
|
||||
return NucelarMonitor.RE_TO_SNAKE.sub(callback, string).lower()
|
||||
|
||||
class Response:
|
||||
|
||||
def __init__(self:Self,
|
||||
nucelar_monitor:type[Self],
|
||||
response:Optional[Any] = None,
|
||||
mime:Optional[str] = None,
|
||||
code:Optional[int] = None,
|
||||
message:Optional[str] = None
|
||||
) -> None:
|
||||
|
||||
default_code:int
|
||||
default_message:str
|
||||
|
||||
self.nucelar_monitor:NucelarMonitor = nucelar_monitor
|
||||
default_code, default_message = self.nucelar_monitor.get_http_default_code()
|
||||
self.body:bytes = b""
|
||||
self.mime:str
|
||||
self.code:str = code or default_code
|
||||
self.message:str = default_message if message is None else message
|
||||
|
||||
self.set_data(response, mime)
|
||||
|
||||
def set_data(self:Self, data:Any|None, mime:Optional[str] = None) -> None:
|
||||
if isinstance(data, bytes):
|
||||
self.body = data
|
||||
self.mime = mime or "application/octet-stream"
|
||||
elif isinstance(data, str):
|
||||
self.body = data.encode(self.nucelar_monitor.get_encoder())
|
||||
self.mime = mime or "text/plain;charset=" + self.nucelar_monitor.get_encoder()
|
||||
elif isinstance(data, (dict, tuple, list)):
|
||||
self.body = json_encode(data).encode(self.nucelar_monitor.get_encoder())
|
||||
self.mime = mime or "application/json;charset=" + self.nucelar_monitor.get_encoder()
|
||||
else:
|
||||
self.body = str(data).encode(self.nucelar_monitor.get_encoder())
|
||||
self.mime = mime or "text/plain;charset=" + self.nucelar_monitor.get_encoder()
|
||||
|
||||
def get_parameters(self:Self) -> dict[str, Any|None]:
|
||||
return {
|
||||
"http_code" : self.code,
|
||||
"http_message" : self.message,
|
||||
"mime" : self.mime,
|
||||
"length" : len(self.body)
|
||||
}
|
||||
|
||||
def __init__(self:Self, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None:
|
||||
|
||||
key:str
|
||||
|
||||
self.__inputs:dict[str, Any|None] = self.get_dictionary(inputs)
|
||||
self.__sentences:dict[str, dict[str, str|Sequence[str]]] = self.DEFAULT_I18N
|
||||
self.__language:str = self.get("language", None, "english")
|
||||
self.__print_format:str = self.get("print_format")
|
||||
self.__print_types:list[list[str]] = self.DEFAULT_SETTINGS["print_types"]
|
||||
self.__exception_format:str = self.get("exception_format")
|
||||
self.__controllers:dict[str, list[tuple[
|
||||
REPattern,
|
||||
tuple[tuple[str, ...]],
|
||||
Callable[[NucelarMonitor.Request, NucelarMonitor.Response], None]|None,
|
||||
str|None]
|
||||
]] = {}
|
||||
self.__http_host:str = self.get("http_host")
|
||||
self.__http_port:int = self.get("http_port")
|
||||
self.__http_server:Socket
|
||||
self.__http_buffer_size:int = self.get("http_cache_size")
|
||||
self.__http_header_response:str = self.get("http_header_response")
|
||||
self.__http_protocol:str = self.get("http_protocol")
|
||||
self.__http_version:str = self.get("http_version")
|
||||
self.__http_code:int = self.get("http_code")
|
||||
self.__http_message:str = self.get("http_message")
|
||||
self.__http_encoder:str = self.get("http_encoder")
|
||||
self.__index_files:tuple[str, ...] = tuple(self.get("index_files"))
|
||||
self.__started:bool = False
|
||||
self.__working:bool = False
|
||||
self.__root_paths:list[str] = ["", self.ROOT]
|
||||
|
||||
for _ in range(2):
|
||||
self.__root_paths.append(self.RE_LAST_DIRECTORY.sub(r'\1', self.__root_paths[-1]))
|
||||
|
||||
for key in ("default_controllers", "controllers"):
|
||||
self.add_controllers(self.get(key))
|
||||
|
||||
self.get("autostart") and self.start()
|
||||
|
||||
def start(self:Self) -> None:
|
||||
if self.__started:
|
||||
return
|
||||
self.__started = True
|
||||
|
||||
self.__http_server = Socket(ADDRESS_FAMILY_IPV4, SOCKET_STREAM)
|
||||
self.__working = True
|
||||
|
||||
try:
|
||||
|
||||
self.__http_server.setsockopt(SOCKET_LAYER, SOCKET_REUSE_ADDRESS, 1)
|
||||
self.__http_server.bind((self.__http_host, self.__http_port))
|
||||
self.__http_server.listen(self.get("http_maximum_connections"))
|
||||
|
||||
Thread(target = self.__listen).start()
|
||||
|
||||
except Exception as exception:
|
||||
self.exception(exception, "http_server_start_exception", {
|
||||
"host" : self.__http_host,
|
||||
"port" : self.__http_port,
|
||||
})
|
||||
self.close()
|
||||
|
||||
def close(self:Self) -> None:
|
||||
if not self.__started:
|
||||
return
|
||||
|
||||
self.__started = False
|
||||
self.__working = False
|
||||
|
||||
try:
|
||||
self.__http_server.close()
|
||||
except Exception as exception:
|
||||
self.exception(exception, "http_server_close_exception", {
|
||||
"host" : self.__http_host,
|
||||
"port" : self.__http_port,
|
||||
})
|
||||
|
||||
def get_print_type(self:Self, _type:str) -> str:
|
||||
|
||||
group:list[str]
|
||||
|
||||
for group in self.__print_types:
|
||||
if _type in group:
|
||||
return group[0].upper()
|
||||
return self.__print_types[0][0].upper()
|
||||
|
||||
def print(self:Self,
|
||||
_type:str,
|
||||
message:str|Sequence[str],
|
||||
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||
i:int = 0
|
||||
) -> None:
|
||||
|
||||
date:datetime = datetime.datetime.now()
|
||||
own:dict[str, Any|None] = {
|
||||
"raw_type" : _type,
|
||||
"type" : self.get_print_type(_type),
|
||||
"i18n" : self.get_texts(message),
|
||||
"message" : self.i18n(message, inputs),
|
||||
**self.get_dictionary(inputs),
|
||||
**self.get_action_data(i + 1)
|
||||
}
|
||||
|
||||
for key in ("year", "month", "day", "hour", "minute", "second"):
|
||||
|
||||
k:str = "i" if key == "minute" else key[0]
|
||||
|
||||
own[k] = own[key] = getattr(date, key)
|
||||
own[k + k] = ("00" + str(own[key]))[-2:]
|
||||
|
||||
own["yyyy"] = own["year"]
|
||||
|
||||
print(self.string_variables(self.__print_format, own) + (own["end"] if "end" in own else ""))
|
||||
|
||||
def exception(self:Self,
|
||||
exception:Exception,
|
||||
message:str|Sequence[str],
|
||||
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||
i:int = 0
|
||||
) -> None:
|
||||
|
||||
lines:list[str] = extract_traceback(exception.__traceback__).format()
|
||||
matches:REMatch = self.RE_EXCEPTION.match(lines[-1])
|
||||
data:dict[str, Any|None] = {
|
||||
**self.get_dictionary(inputs),
|
||||
"lines" : "",
|
||||
"exception_message" : str(exception),
|
||||
"method" : matches.group(3),
|
||||
"line" : matches.group(2),
|
||||
"file" : matches.group(1)
|
||||
}
|
||||
block:str
|
||||
j:int
|
||||
|
||||
for j, block in enumerate(trace_format_stack()[:-2] + lines):
|
||||
if block:
|
||||
data["lines"] += "\n " + str(j) + " - " + self.RE_NEW_LINE.split(block.strip())[0]
|
||||
|
||||
data["end"] = self.string_variables(self.__exception_format, data)
|
||||
|
||||
message and self.print("exception", message, data, i + 2)
|
||||
|
||||
@classmethod
|
||||
def fix_path(cls:type[Self], path:str) -> str:
|
||||
return cls.RE_SLASHES.sub(cls.SLASH, path)
|
||||
|
||||
def get_absolute_path(self:Self, path:str) -> str|None:
|
||||
|
||||
root:str
|
||||
absolute:str
|
||||
|
||||
for root in self.__root_paths:
|
||||
absolute = self.fix_path(root + '/' + path)
|
||||
if path_exists(absolute):
|
||||
return absolute
|
||||
return None
|
||||
|
||||
def load_file(self:Self, path:str, mode:str = "r") -> str|bytes|None:
|
||||
|
||||
path:str = self.get_absolute_path(path)
|
||||
|
||||
if path:
|
||||
with open(path, mode) as file:
|
||||
return file.read()
|
||||
return None
|
||||
|
||||
def load_json(self:Self, data:str|dict[str, Any|None]|list[Any|None]) -> dict[str, Any|None]|list[Any|None]|None:
|
||||
if isinstance(data, str):
|
||||
|
||||
json:list[Any|None]|dict[str, Any|None]|None
|
||||
|
||||
try:
|
||||
json = json_decode(data)
|
||||
except Exception as exception:
|
||||
self.exception(exception, "load_json_exception", {
|
||||
"data" : data,
|
||||
"length" : len(data)
|
||||
})
|
||||
|
||||
if json:
|
||||
return json
|
||||
try:
|
||||
return json_decode(self.load_file(data))
|
||||
except Exception as exception:
|
||||
self.exception(exception, "load_json_by_file_exception", {
|
||||
"path" : data
|
||||
})
|
||||
return None
|
||||
elif isinstance(data, (dict, list)):
|
||||
return data
|
||||
return None
|
||||
|
||||
def get_encoder(self:Self) -> str:
|
||||
return self.__http_encoder
|
||||
|
||||
def get_http_default_code(self:Self) -> tuple[int, str]:
|
||||
return self.__http_code, self.__http_message
|
||||
|
||||
def get(self:Self,
|
||||
keys:str|Sequence[str],
|
||||
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||
default:Optional[Any] = None
|
||||
) -> Any|None:
|
||||
return self.get_value(keys, (inputs, self.__inputs, self.DEFAULT_SETTINGS), default)
|
||||
|
||||
def __get_text(self:Self, strings:str|Sequence[str]) -> str:
|
||||
|
||||
keys:list[str] = self.get_keys(strings := self.get_list(strings))
|
||||
|
||||
if len(keys):
|
||||
|
||||
language:str
|
||||
used:list[str] = []
|
||||
|
||||
for language in [self.__language] + list(self.__sentences.keys()):
|
||||
if language not in used and language in self.__sentences:
|
||||
|
||||
key:str
|
||||
|
||||
used.append(language)
|
||||
for key in keys:
|
||||
if key in self.__sentences[language]:
|
||||
return self.__sentences[language][key]
|
||||
return strings[0]
|
||||
|
||||
def i18n(self:Self,
|
||||
strings:str|Sequence[str],
|
||||
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None
|
||||
) -> str:
|
||||
return self.string_variables(self.__get_text(strings), inputs)
|
||||
|
||||
def add_controllers(self:Self,
|
||||
inputs:str|dict[str, dict[str, str|Callable[[Request], None]]]|Sequence[Any|None]
|
||||
) -> None:
|
||||
if isinstance(inputs, dict):
|
||||
|
||||
method:str
|
||||
controllers:dict[str, str|Callable[[NucelarMonitor.Request], None]]
|
||||
|
||||
for method, controllers in inputs.items():
|
||||
if (method := method.lower()) not in self.__controllers:
|
||||
self.__controllers[method] = []
|
||||
if isinstance(controllers, dict):
|
||||
|
||||
request:str
|
||||
target:str|Callable[[NucelarMonitor.Request], None]
|
||||
|
||||
for request, target in controllers.items():
|
||||
|
||||
controller:Callable[[NucelarMonitor.Request, NucelarMonitor.Response], None]|None = None
|
||||
path:str|None = None
|
||||
|
||||
if isinstance(target, str) and (controller := getattr(self, target, None)) is None:
|
||||
path = self.get_absolute_path(target)
|
||||
|
||||
if callable(controller) or path is not None:
|
||||
|
||||
variables:list[str] = []
|
||||
|
||||
def callback(matches:REMatch) -> str:
|
||||
|
||||
variables.append(matches.group(1))
|
||||
|
||||
return r'([^\/]+)'
|
||||
|
||||
self.__controllers[method].append((re_compile(r'^' + self.RE_ROUTE_KEY.sub(callback, self.to_regular_expression(
|
||||
request[:-1] if request[-1] == "/" else request
|
||||
)) + (r'' if path is None else r'(.*)') + r'\/?$'), tuple(variables), controller, path))
|
||||
|
||||
elif isinstance(inputs, (list, tuple)):
|
||||
|
||||
subinputs:Any|None
|
||||
|
||||
for subinputs in inputs:
|
||||
self.add_controllers(subinputs)
|
||||
|
||||
elif isinstance(inputs, str):
|
||||
self.add_controllers(self.load_json(inputs))
|
||||
|
||||
def __listen(self:Self) -> None:
|
||||
while self.__working:
|
||||
try:
|
||||
|
||||
client:Socket
|
||||
address:str
|
||||
port:int
|
||||
|
||||
client, (address, port) = self.__http_server.accept()
|
||||
|
||||
Thread(
|
||||
target = self.__listen_client,
|
||||
args = (client, address, port)
|
||||
).start()
|
||||
|
||||
except Exception as exception:
|
||||
self.exception(exception, "http_server_listen_exception", {
|
||||
"host" : self.__http_host,
|
||||
"port" : self.__http_port,
|
||||
})
|
||||
|
||||
def __listen_client(self:Self, client:Socket, address:str, port:int) -> None:
|
||||
|
||||
data:bytes = b""
|
||||
route:str = ""
|
||||
method:str = "UNKN"
|
||||
response:NucelarMonitor.Response = NucelarMonitor.Response(self)
|
||||
|
||||
try:
|
||||
|
||||
request:NucelarMonitor.Request
|
||||
variables:tuple[str, ...]
|
||||
controller:Callable[[NucelarMonitor.Request], Any|None]|None
|
||||
path:str|None
|
||||
response_data:Any|None = None
|
||||
pattern:REPattern
|
||||
done:bool = False
|
||||
|
||||
while True:
|
||||
|
||||
buffer:bytes = client.recv(self.__http_buffer_size)
|
||||
|
||||
if not buffer:
|
||||
break
|
||||
data += buffer
|
||||
if len(buffer) != self.__http_buffer_size:
|
||||
break
|
||||
|
||||
for pattern, variables, controller, path in self.__controllers[
|
||||
method := (request := self.Request(data, self.__http_encoder)).method
|
||||
]:
|
||||
|
||||
matches:REMatch = pattern.match(route := request.request)
|
||||
|
||||
if matches is not None:
|
||||
request.set_uri_variables(variables, matches)
|
||||
if done := path is not None:
|
||||
for index in self.__index_files:
|
||||
|
||||
full_path = path + "/" + route + ("" if index == "" else "/" + index)
|
||||
|
||||
if done := (response_data := self.load_file(full_path, "rb")) is not None:
|
||||
response.set_data(
|
||||
response_data,
|
||||
get_mime_by_extension(full_path)[0] or "application/octet-stream"
|
||||
)
|
||||
break
|
||||
|
||||
elif done := controller is not None:
|
||||
controller(request, response)
|
||||
|
||||
if done:
|
||||
break
|
||||
|
||||
|
||||
if not done:
|
||||
response.body = b"<h1>Not Found</h1>"
|
||||
response.mime = "text/html;charset=" + self.__http_encoder
|
||||
response.code = "404"
|
||||
response.message = "Not Found"
|
||||
|
||||
client.sendall(self.string_variables(self.__http_header_response, {
|
||||
"http_protocol" : self.__http_protocol,
|
||||
"http_version" : self.__http_version,
|
||||
**response.get_parameters()
|
||||
}).encode(self.__http_encoder) + response.body)
|
||||
client.close()
|
||||
|
||||
except Exception as exception:
|
||||
self.exception(exception, "http_server_client_exception", {
|
||||
"host" : self.__http_host,
|
||||
"port" : self.__http_port,
|
||||
"client_address" : address,
|
||||
"client_port" : port,
|
||||
"length" : len(data),
|
||||
"method" : method,
|
||||
"route" : route,
|
||||
"response_length" : len(response.body)
|
||||
})
|
||||
|
||||
def debian(self:Self, request:Request, response:Response) -> None:
|
||||
|
||||
key:str = request.get("key")
|
||||
hostnames:list[str]
|
||||
domain:str|None
|
||||
interfaces:list[list[int, str, bool, str, int]]
|
||||
disks:list[list[str, int, int, str|None]]
|
||||
iterations:int
|
||||
candle_times:list[int, int]
|
||||
cpu:list[float, float, float, float, float]
|
||||
memory:list[int, int, int, int, int, float]
|
||||
net_use:list[list[list[str, int, int, int, int, int, int]]]
|
||||
|
||||
hostnames, domain, interfaces, disks, iterations, candle_times, cpu, memory, net_use = json_decode(request.body)
|
||||
|
||||
@classmethod
|
||||
def get_dictionary(cls:type[Self], *items:Sequence[Any|None]) -> dict[str, Any|None]:
|
||||
|
||||
dictionary:dict[str, Any|None] = {}
|
||||
item:Any|None
|
||||
|
||||
for item in items:
|
||||
if isinstance(item, dict):
|
||||
dictionary.update(item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
|
||||
subitem:Any|None
|
||||
|
||||
for subitem in item:
|
||||
dictionary.update(cls.get_dictionary(subitem))
|
||||
|
||||
return dictionary
|
||||
|
||||
@classmethod
|
||||
def get_keys(cls:type[Self], *items:Sequence[Any|None]) -> list[str]:
|
||||
|
||||
keys:list[str] = []
|
||||
item:Any|None
|
||||
|
||||
for item in items:
|
||||
if isinstance(item, str):
|
||||
cls.RE_KEY.match(item) and keys.append(item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
|
||||
subitem:Any|None
|
||||
|
||||
for subitem in item:
|
||||
keys.extend(cls.get_keys(subitem))
|
||||
|
||||
return keys
|
||||
|
||||
@classmethod
|
||||
def get_dictionaries(cls:type[Self], *items:Sequence[Any|None]) -> list[dict[str, Any|None]]:
|
||||
|
||||
dictionaries:list[dict[str, Any|None]] = []
|
||||
item:Any|None
|
||||
|
||||
for item in items:
|
||||
if isinstance(item, dict):
|
||||
dictionaries.append(item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
|
||||
subitem:Any|None
|
||||
|
||||
for subitem in item:
|
||||
dictionaries.extend(cls.get_dictionaries(subitem))
|
||||
|
||||
return dictionaries
|
||||
|
||||
@classmethod
|
||||
def get_value(cls:type[Self],
|
||||
keys:str|Sequence[str],
|
||||
inputs:dict[str, Any|None]|Sequence[Any|None],
|
||||
default:Optional[Any] = None
|
||||
) -> Any|None:
|
||||
if len(cls.get_keys(keys)):
|
||||
|
||||
dictionary:dict[str, Any|None]
|
||||
|
||||
for dictionary in cls.get_dictionaries(inputs):
|
||||
|
||||
key:str
|
||||
|
||||
for key in cls.get_keys(keys):
|
||||
if key in dictionary:
|
||||
return dictionary[key]
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
def get_list(item:Any|None) -> list[Any|None]:
|
||||
return item if isinstance(item, (list, tuple)) else [item]
|
||||
|
||||
@classmethod
|
||||
def string_variables(cls:type[Self],
|
||||
string:str,
|
||||
inputs:dict[str, Any|None]|Sequence[Any|None],
|
||||
default:Optional[str] = None
|
||||
) -> str:
|
||||
|
||||
variables:dict[str, Any|None] = cls.get_dictionary(inputs)
|
||||
|
||||
def callback(matches:REMatch) -> str:
|
||||
|
||||
key:str = matches.group(1)
|
||||
|
||||
return (
|
||||
str(variables[key]) if key in variables else
|
||||
default if default is not None else
|
||||
matches.group(0))
|
||||
|
||||
return cls.RE_STRING_VARIABLE.sub(callback, string)
|
||||
|
||||
@staticmethod
|
||||
def get_texts(*items:list[Any|None]) -> list[str]:
|
||||
|
||||
texts:list[str] = []
|
||||
item:Any|None
|
||||
|
||||
for item in items:
|
||||
if isinstance(item, str):
|
||||
texts.append(item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
|
||||
subitem:Any|None
|
||||
|
||||
for subitem in item:
|
||||
texts.extend(NucelarMonitor.get_texts(subitem))
|
||||
|
||||
return texts
|
||||
|
||||
@staticmethod
|
||||
def get_action_data(i:int = 0) -> dict[str, str|int]:
|
||||
|
||||
stack:FrameInfo = get_stack()[i]
|
||||
|
||||
return {
|
||||
"file" : stack.filename,
|
||||
"method" : stack.function,
|
||||
"line" : stack.lineno
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def to_regular_expression(cls:type[Self], string:str) -> str:
|
||||
|
||||
def callback(matches:REMatch) -> str:
|
||||
|
||||
character:str = matches.group(0)
|
||||
|
||||
return "\\" + (
|
||||
cls.SPECIAL_REGULAR_EXPRESSION_CHARACTERS[character] if character in cls.SPECIAL_REGULAR_EXPRESSION_CHARACTERS else
|
||||
character)
|
||||
|
||||
return cls.RE_TO_REGULAR_EXPRESSION.sub(callback, string)
|
||||
6
Python/run.py
Normal file
6
Python/run.py
Normal file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from NucelarMonitor import NucelarMonitor
|
||||
|
||||
nucelar_monitor:NucelarMonitor = NucelarMonitor()
|
||||
47
README.md
47
README.md
@ -1,3 +1,48 @@
|
||||
# NucelarMonitor
|
||||
|
||||
NucelarMonitor is a very single project for monitoring OS and their Hardware and services in Stream via Web from server.
|
||||
NucelarMonitor is a very single project for monitoring OS and their Hardware and services in Stream via Web from server.
|
||||
|
||||
# Notes
|
||||
|
||||
Datos de envío Debian:
|
||||
|
||||
0. `list[str]`: Hostnames.
|
||||
1. `str|None`: Domain.
|
||||
2. `list[list[int, str, bool, str, int]]`: Interfaces de red. Por cada uno:
|
||||
0. `int`: i. Identificador de posición.
|
||||
1. `str`: Nombre.
|
||||
2. `bool`: ¿Es IPv6?
|
||||
3. `str`: IP.
|
||||
4. `int`: Máscara.
|
||||
3. `list[list[str, int, int, str|None]]`: Discos. Por cada uno:
|
||||
0. `str`: Nombre.
|
||||
1. `int`: Capacidad.
|
||||
2. `int`: Espacio libre.
|
||||
3. `str|None`: Punto de montaje.
|
||||
4. `int`: Iteraciones o ciclos de conteo de las velas.
|
||||
5. `list[int, int]`: Timestamp de inicio y de fin de las velas.
|
||||
0. `int`: Timestamp de inicio.
|
||||
1. `int`: Timestamp de fin.
|
||||
6. `list[float, float, float, float, float]`: Vela de uso porcentual de la CPU:
|
||||
0. `float`: Entrada.
|
||||
1. `float`: Salida.
|
||||
2. `float`: Mínimo.
|
||||
3. `float`: Máximo.
|
||||
4. `float`: Media.
|
||||
7. `list[int, int, int, int, int, float]`: Vela de uso de la memoria RAM.
|
||||
0. `int`: Total de memoria.
|
||||
1. `int`: Entrada.
|
||||
2. `int`: Salida.
|
||||
3. `int`: Mínimo.
|
||||
4. `int`: Máximo.
|
||||
5. `float`: Media.
|
||||
8. `list[list[list[str, int, int, int, int, int, int]]]`: Uso de Red. Está diseñado en un proceso de diferencia Entrada/Salida. Es una lista de dos listas, entrada y salida, el segundo nivel tiene una lista por cada interfaz de red, las cuales tienen:
|
||||
0. `str`: Nombre. Identifica la interfaz de red.
|
||||
1. `int`: Bytes recepcionados actualmente.
|
||||
2. `int`: Paquetes recepcionados actualmente.
|
||||
3. `int`: Errores en recepción actualmente.
|
||||
4. `int`: Bytes enviados actualmente.
|
||||
5. `int`: Paquetes enviados actualmente.
|
||||
6. `int`: Errores en envío actualmente.
|
||||
|
||||
La idea es procesar el uso de red en Python.
|
||||
609
SQLServer/NucelarMonitor.server.sql
Normal file
609
SQLServer/NucelarMonitor.server.sql
Normal file
@ -0,0 +1,609 @@
|
||||
if (select top 1 0 from sys.databases where name = 'NucelarMonitor') is null create database NucelarMonitor collate Latin1_General_100_CI_AS_SC_UTF8
|
||||
go
|
||||
use NucelarMonitor
|
||||
|
||||
if object_id(N'dbo.tables_drop', N'P') is not null drop procedure dbo.tables_drop
|
||||
go
|
||||
create procedure dbo.tables_drop as begin
|
||||
|
||||
set nocount on
|
||||
|
||||
-- Level Plains.
|
||||
|
||||
-- Level 2.
|
||||
if object_id(N'dbo.MachineInterfacesData', N'U') is not null drop table dbo.MachineInterfacesData
|
||||
if object_id(N'dbo.MachineInterfacesTraffic', N'U') is not null drop table dbo.MachineInterfacesTraffic
|
||||
if object_id(N'dbo.MachineDisksSpace', N'U') is not null drop table dbo.MachineDisksSpace
|
||||
if object_id(N'dbo.Exceptions', N'U') is not null drop table dbo.Exceptions
|
||||
|
||||
-- Level 1.
|
||||
if object_id(N'dbo.MachineInterfaces', N'U') is not null drop table dbo.MachineInterfaces
|
||||
if object_id(N'dbo.MachineDisks', N'U') is not null drop table dbo.MachineDisks
|
||||
if object_id(N'dbo.MachineRAM', N'U') is not null drop table dbo.MachineRAM
|
||||
if object_id(N'dbo.MachineCPU', N'U') is not null drop table dbo.MachineCPU
|
||||
if object_id(N'dbo.Procedures', N'U') is not null drop table dbo.Procedures
|
||||
|
||||
-- Level 0.
|
||||
if object_id(N'dbo.CandlesTimes', N'U') is not null drop table dbo.CandlesTimes
|
||||
if object_id(N'dbo.Interfaces', N'U') is not null drop table dbo.Interfaces
|
||||
if object_id(N'dbo.Disks', N'U') is not null drop table dbo.Disks
|
||||
if object_id(N'dbo.Hostnames', N'U') is not null drop table dbo.Hostnames
|
||||
if object_id(N'dbo.Domains', N'U') is not null drop table dbo.Domains
|
||||
if object_id(N'dbo.Machines', N'U') is not null drop table dbo.Machines
|
||||
if object_id(N'dbo.Databases', N'U') is not null drop table dbo.Databases
|
||||
if object_id(N'dbo.Messages', N'U') is not null drop table dbo.Messages
|
||||
if object_id(N'dbo.BigData', N'U') is not null drop table dbo.BigData
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.tables_create', N'P') is not null drop procedure dbo.tables_create
|
||||
go
|
||||
create procedure dbo.tables_create as begin
|
||||
|
||||
set nocount on
|
||||
|
||||
-- Level 0.
|
||||
if object_id(N'dbo.Machines', N'U') is null create table dbo.Machines(
|
||||
id integer not null identity(1, 1),
|
||||
[key] varchar(32) not null,
|
||||
[description] varchar(512),
|
||||
date_in datetime not null constraint machines_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machines_pk primary key clustered (id),
|
||||
constraint machines_uk_key unique ([key]),
|
||||
constraint machines_ck_key check ([key] like '[a-zA-Z0-9][a-zA-Z0-9_]{0,31}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Domains', N'U') is null create table dbo.Domains(
|
||||
id integer not null identity(1, 1),
|
||||
domain varchar(64) not null,
|
||||
[description] varchar(512),
|
||||
date_in datetime not null constraint domains_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint domains_pk primary key clustered (id),
|
||||
constraint domains_uk_domain unique nonclustered (domain asc) with (fillfactor = 90),
|
||||
constraint domains_ck_domain check ([domain] like '[a-zA-Z0-9_-.]{1,64}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
|
||||
if object_id(N'dbo.Hostnames', N'U') is null create table dbo.Hostnames(
|
||||
id integer not null identity(1, 1),
|
||||
[name] varchar(32) not null,
|
||||
[description] varchar(512),
|
||||
date_in datetime not null constraint hostnames_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint hostnames_pk primary key clustered (id),
|
||||
constraint hostnames_uk_name unique nonclustered ([name] asc) with (fillfactor = 90),
|
||||
constraint hostnames_ck_name check ([name] like '[a-zA-Z0-9_-]{1,32}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Disks', N'U') is null create table dbo.Disks(
|
||||
id integer not null identity(1, 1),
|
||||
[name] varchar(32) not null,
|
||||
[size] bigint not null,
|
||||
mountpoint varchar(128) not null,
|
||||
[description] varchar(512),
|
||||
date_in datetime not null constraint disks_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint disks_pk primary key clustered (id),
|
||||
constraint disks_uk_name unique nonclustered ([name] asc, mountpoint asc) with (fillfactor = 90),
|
||||
constraint disks_ck_name check (
|
||||
[name] like '[a-zA-Z0-9_-]{1,32}' or
|
||||
mountpoint like '[A-Z]:'
|
||||
) with (fillfactor = 90),
|
||||
constraint disks_ck_size check (size >= 0 and size < power(2, 53)) with (fillfactor = 90),
|
||||
constraint disks_ck_mountpoint check (
|
||||
mountpoint like '/%' or
|
||||
mountpoint like '[a-zA-Z]:\%' or
|
||||
mountpoint like '\\%'
|
||||
) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Interfaces', N'U') is null create table dbo.Interfaces(
|
||||
id integer not null identity(1, 1),
|
||||
[name] varchar(32) not null,
|
||||
[description] varchar(512),
|
||||
date_in datetime not null constraint interfaces_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint interfaces_pk primary key clustered (id),
|
||||
constraint interfaces_uk_machine_name unique nonclustered (machine asc, [name] asc) with (fillfactor = 90),
|
||||
constraint interfaces_ck_name check ([name] like '[a-zA-Z0-9_-]{1,32}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.CandlesTimes', N'U') is null create table dbo.CandlesTimes(
|
||||
id integer not null identity(1, 1),
|
||||
[from] datetime not null,
|
||||
[to] datetime not null,
|
||||
date_in datetime not null constraint candles_times_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint candles_times_pk primary key clustered (id),
|
||||
constraint candles_times_uk_from_to unique nonclustered ([from] asc, [to] asc) with (fillfactor = 90),
|
||||
constraint candles_times_ck_from_to check ([from] < [to]) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.BigData', N'U') is null create table dbo.BigData(
|
||||
id integer not null identity(1, 1),
|
||||
[hash] binary(64) not null,
|
||||
[value] varchar(max) not null,
|
||||
date_in datetime not null constraint big_data_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint big_data_pk primary key clustered (id),
|
||||
constraint big_data_uk_hash unique nonclustered ([hash] asc) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Messages', N'U') is null create table dbo.Messages(
|
||||
id integer not null identity(1, 1),
|
||||
[key] varchar(128) not null,
|
||||
date_in datetime not null constraint messages_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint messages_pk primary key clustered (id),
|
||||
constraint messages_ck_key check ([key] like '[a-zA-Z_][a-zA-Z0-9_]{0,127}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Databases', N'U') is null create table dbo.Databases(
|
||||
id integer not null identity(1, 1),
|
||||
[name] varchar(64) not null,
|
||||
date_in datetime not null constraint databases_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint databases_pk primary key clustered (id),
|
||||
constraint databases_uk_name unique nonclustered ([name] asc) with (fillfactor = 90),
|
||||
constraint databases_ck_name check ([name] like '[a-zA-Z_][a-zA-Z0-9_]{0,63}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
-- Level 1.
|
||||
if object_id(N'dbo.MachineCPU', N'U') is null create table dbo.MachineCPU(
|
||||
id integer not null identity(1, 1),
|
||||
machine integer not null,
|
||||
candle_time integer not null,
|
||||
[in] float not null,
|
||||
[out] float not null,
|
||||
minimum float not null,
|
||||
maximum float not null,
|
||||
average float not null,
|
||||
date_in datetime not null constraint machine_cpu_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_cpu_pk primary key clustered (id),
|
||||
constraint machine_cpu_fk_machine foreign key (machine) references dbo.Machines(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_cpu_fk_candle_time foreign key (candle_time) references dbo.CandlesTimes(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_cpu_ck_cpu_in check (
|
||||
[in] between 0 and 100 and
|
||||
[in] between minimum and maximum
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_cpu_ck_cpu_out check (
|
||||
[out] between 0 and 100 and
|
||||
[out] between minimum and maximum
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_cpu_ck_cpu_minimum check (
|
||||
minimum between 0 and 100 and
|
||||
minimum <= maximum
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_cpu_ck_cpu_maximum check (
|
||||
maximum between 0 and 100 and
|
||||
maximum >= minimum
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_cpu_ck_cpu_average check (
|
||||
average between 0 and 100 and
|
||||
average between minimum and maximum
|
||||
) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.MachineRAM', N'U') is null create table dbo.MachineRAM(
|
||||
id integer not null identity(1, 1),
|
||||
machine integer not null,
|
||||
candle_time integer not null,
|
||||
total bigint not null,
|
||||
[in] bigint not null,
|
||||
[out] bigint not null,
|
||||
minimum bigint not null,
|
||||
maximum bigint not null,
|
||||
average bigint not null,
|
||||
date_in datetime not null constraint machine_ram_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_ram_pk primary key clustered (id),
|
||||
constraint machine_ram_fk_machine foreign key (machine) references dbo.Machines(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_ram_fk_candle_time foreign key (candle_time) references dbo.CandlesTimes(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_ram_ck_memory_total check (
|
||||
total between 0 and power(2, 53) - 1
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_ram_ck_memory_in check (
|
||||
[in] between 0 and power(2, 53) - 1 and
|
||||
[in] between minimum and maximum and
|
||||
[in] <= total
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_ram_ck_memory_out check (
|
||||
[out] between 0 and power(2, 53) - 1 and
|
||||
[out] between minimum and maximum and
|
||||
[out] <= total
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_ram_ck_memory_minimum check (
|
||||
minimum between 0 and power(2, 53) - 1 and
|
||||
minimum <= total and
|
||||
minimum <= maximum
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_ram_ck_memory_maximum check (
|
||||
maximum between 0 and power(2, 53) - 1 and
|
||||
maximum between total and minimum
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_ram_ck_memory_average check (
|
||||
average between 0 and power(2, 53) - 1 and
|
||||
average between minimum and maximum and
|
||||
average <= total
|
||||
) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.MachineDisks', N'U') is null create table dbo.MachineDisks(
|
||||
id integer not null identity(1, 1),
|
||||
machine integer not null,
|
||||
[disk] integer not null,
|
||||
belongs bit not null constraint machine_disks_df_belongs default 1,
|
||||
mounted bit not null constraint machine_disks_df_mounted default 1,
|
||||
date_in datetime not null constraint machine_disks_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_disks_pk primary key clustered (id),
|
||||
constraint machine_disks_fk_machine foreign key (machine) references dbo.Machines(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_disks_fk_disk foreign key ([disk]) references dbo.Disks(id)
|
||||
on update no action
|
||||
on delete no action
|
||||
)
|
||||
|
||||
if object_id(N'dbo.MachineInterfaces', N'U') is null create table dbo.MachineInterfaces(
|
||||
id integer not null identity(1, 1),
|
||||
machine integer not null,
|
||||
[interface] integer not null,
|
||||
belongs bit not null constraint machine_interfaces_df_belongs default 1,
|
||||
mounted bit not null constraint machine_interfaces_df_mounted default 1,
|
||||
date_in datetime not null constraint machine_interfaces_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_interfaces_pk primary key clustered (id),
|
||||
constraint machine_interfaces_fk_machine foreign key (machine) references dbo.Machines(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_interfaces_fk_interface foreign key ([interface]) references dbo.Interfaces(id)
|
||||
on update no action
|
||||
on delete no action
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Procedures', N'U') is null create table dbo.Procedures(
|
||||
id integer not null identity(1, 1),
|
||||
[database] integer not null,
|
||||
[name] varchar(64) not null,
|
||||
date_in datetime not null constraint procedures_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint procedures_pk primary key clustered (id),
|
||||
constraint procedures_fk_database foreign key ([database]) references dbo.Databases(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint procedures_uk_name unique nonclustered ([database] asc, [name] asc) with (fillfactor = 90),
|
||||
constraint procedures_ck_name check ([name] like '[a-zA-Z_][a-zA-Z0-9_]{0,63}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
-- Level 2.
|
||||
if object_id(N'dbo.MachineDisksSpace', N'U') is null create table dbo.MachineDisksSpace(
|
||||
id integer not null identity(1, 1),
|
||||
machine_disk integer not null,
|
||||
candle_time integer not null,
|
||||
free bigint not null,
|
||||
date_in datetime not null constraint machine_disks_space_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_disks_space_pk primary key clustered (id),
|
||||
constraint machine_disks_space_fk_machine_disk foreign key (machine_disk) references dbo.MachineDisks(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_disks_space_fk_candle_time foreign key (candle_time) references dbo.CandlesTimes(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_disks_space_ck_free check (
|
||||
free between 0 and power(2, 53) - 1 and
|
||||
free <= isnull((
|
||||
select top 1 disks.[size]
|
||||
from dbo.Disks disks
|
||||
join dbo.MachineDisks machine_disks on machine_disks.[disk] = disks.id
|
||||
where
|
||||
disks.date_out is null and
|
||||
machine_disks.date_out is null and
|
||||
machine_disks.belongs = 1 and
|
||||
machine_disks.id = machine_disk
|
||||
), 0)
|
||||
) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.MachineInterfacesTraffic', N'U') is null create table dbo.MachineInterfacesTraffic(
|
||||
id integer not null identity(1, 1),
|
||||
machine_interface integer not null,
|
||||
candle_time integer not null,
|
||||
bytes bigint not null,
|
||||
packages integer not null,
|
||||
errors integer not null,
|
||||
date_in datetime not null constraint machine_interfaces_traffic_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_interfaces_traffic_pk primary key clustered (id),
|
||||
constraint machine_interfaces_traffic_fk_machine_interface foreign key (machine_interface) references dbo.MachineInterfaces(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_interfaces_traffic_fk_candle_time foreign key (candle_time) references dbo.CandlesTimes(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_interfaces_traffic_ck_bytes check (
|
||||
bytes between 0 and power(2, 53) - 1
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_interfaces_traffic_ck_packages check (
|
||||
packages between 0 and power(2, 31) - 1
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_interfaces_traffic_ck_errors check (
|
||||
errors between 0 and power(2, 31) - 1
|
||||
) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.MachineInterfacesData', N'U') is null create table dbo.MachineInterfacesData(
|
||||
id integer not null identity(1, 1),
|
||||
machine_interface integer not null,
|
||||
is_ipv6 bit not null constraint machine_interfaces_data_df_is_ipv6 default 0,
|
||||
[address] varchar(45) not null,
|
||||
mask tinyint not null,
|
||||
date_in datetime not null constraint machine_interfaces_data_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_interfaces_data_pk primary key clustered (id),
|
||||
constraint machine_interfaces_data_fk_machine_interface foreign key (machine_interface) references dbo.MachineInterfaces(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_interfaces_data_ck_is_ipv6 check (
|
||||
(is_ipv6 = 0 and [address] like '[0-9]%.%.%.%') or
|
||||
(is_ipv6 = 1 and [address] like '%:%')
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_interfaces_data_ck_address check (
|
||||
([address] like '[0-9]%.%.%.%' and mask between 0 and 32) or
|
||||
([address] like '%:%' and mask between 0 and 128)
|
||||
) with (fillfactor = 90),
|
||||
constraint machine_interfaces_data_ck_mask check (
|
||||
(mask between 0 and (case when is_ipv6 = 1 then 128 else 32 end))
|
||||
) with (fillfactor = 90)
|
||||
)
|
||||
|
||||
if object_id(N'dbo.Exceptions', N'U') is null create table dbo.Exceptions(
|
||||
id integer not null identity(1, 1),
|
||||
[procedure] integer not null,
|
||||
[message] integer not null,
|
||||
parameters integer,
|
||||
exception integer not null,
|
||||
[status] varchar(16),
|
||||
code integer,
|
||||
date_in datetime not null constraint exceptions_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint exceptions_pk primary key clustered (id),
|
||||
constraint exceptions_fk_procedure foreign key ([procedure]) references dbo.Procedures(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint exceptions_fk_message foreign key ([message]) references dbo.Messages(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint exceptions_fk_parameters foreign key (parameters) references dbo.BigData(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint exceptions_fk_exception foreign key (exception) references dbo.BigData(id)
|
||||
on update no action
|
||||
on delete no action
|
||||
)
|
||||
|
||||
-- Level Plains.
|
||||
if object_id(N'dbo.MachineInterfacesPlain', N'U') is null create table dbo.MachineInterfacesPlain(
|
||||
id integer not null identity(1, 1),
|
||||
machine integer not null,
|
||||
interface integer not null,
|
||||
machine_interface integer not null,
|
||||
candle_time integer not null,
|
||||
bytes bigint not null,
|
||||
packages integer not null,
|
||||
errors integer not null,
|
||||
is_ipv6 bit not null constraint machine_interfaces_data_df_is_ipv6 default 0,
|
||||
[address] varchar(45) not null,
|
||||
mask tinyint not null,
|
||||
belongs bit not null constraint machine_interfaces_plain_df_belongs default 1,
|
||||
date_in datetime not null constraint machine_interfaces_plain_df_date_in default getdate(),
|
||||
date_out datetime,
|
||||
constraint machine_interfaces_plain_pk primary key clustered (id),
|
||||
constraint machine_interfaces_plain_fk_machine foreign key (machine) references dbo.Machines(id)
|
||||
on update no action
|
||||
on delete no action,
|
||||
constraint machine_interfaces_plain_uk_machine_interface unique nonclustered (machine asc, [interface] asc) with (fillfactor = 90),
|
||||
constraint machine_interfaces_plain_ck_interface check ([interface] like '[a-zA-Z0-9_-]{1,32}') with (fillfactor = 90)
|
||||
)
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.tables_update', N'P') is not null drop procedure dbo.tables_update
|
||||
go
|
||||
create procedure dbo.tables_update as begin
|
||||
|
||||
set nocount on
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.tables_fill', N'P') is not null drop procedure dbo.tables_fill
|
||||
go
|
||||
create procedure dbo.tables_fill as begin
|
||||
|
||||
set nocount on
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
execute dbo.tables_drop
|
||||
go
|
||||
execute dbo.tables_create
|
||||
go
|
||||
execute dbo.tables_update
|
||||
go
|
||||
execute dbo.tables_fill
|
||||
go
|
||||
|
||||
if object_id(N'dbo.hash_big_data', N'FN') is not null drop function dbo.hash_big_data
|
||||
go
|
||||
create function dbo.hash_big_data (@value varchar(max)) returns binary(64) as begin
|
||||
return select top 1 convert(binary(64), hashbytes('SHA2_256', convert(nvarchar(max), @value)))
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.get_procedure', N'P') is not null drop procedure dbo.get_procedure
|
||||
go
|
||||
create procedure dbo.get_procedure
|
||||
@database varchar(64),
|
||||
@procedure varchar(64),
|
||||
@id integer output
|
||||
as begin
|
||||
|
||||
declare @database_id integer = (
|
||||
select top 1 id from dbo.Databases where
|
||||
date_out is null and
|
||||
[name] = @database
|
||||
)
|
||||
|
||||
set nocount on
|
||||
|
||||
if @database_id is null begin
|
||||
insert into dbo.Databases([name]) values (@database)
|
||||
set @database_id = scope_identity()
|
||||
end
|
||||
|
||||
set @id = (
|
||||
select top 1 id from dbo.Procedures where
|
||||
date_out is null and
|
||||
[database] = @database_id and
|
||||
[name] = @procedure
|
||||
)
|
||||
|
||||
if @id is null begin
|
||||
insert into dbo.Procedures([database], [name]) values (@database_id, @procedure)
|
||||
set @id = scope_identity()
|
||||
end
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.get_big_data', N'P') is not null drop procedure dbo.get_big_data
|
||||
go
|
||||
create procedure dbo.get_big_data
|
||||
@value varchar(max),
|
||||
@id integer output
|
||||
as begin
|
||||
|
||||
declare @hash binary(64) = dbo.hash_big_data(@value)
|
||||
|
||||
set nocount on
|
||||
|
||||
set @id = (
|
||||
select top 1 id from dbo.BigData where
|
||||
date_out is null and
|
||||
[hash] = @hash
|
||||
)
|
||||
|
||||
if @id is null begin
|
||||
insert into dbo.BigData([hash], [value]) values (@hash, @value)
|
||||
set @id = scope_identity()
|
||||
end
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.get_message', N'P') is not null drop procedure dbo.get_message
|
||||
go
|
||||
create procedure dbo.get_message
|
||||
@message varchar(128),
|
||||
@id integer output
|
||||
as begin
|
||||
|
||||
set nocount on
|
||||
|
||||
set @id = (
|
||||
select top 1 id from dbo.Messages where
|
||||
date_out is null and
|
||||
[key] = @message
|
||||
)
|
||||
|
||||
if @id is null begin
|
||||
insert into dbo.Messages([key]) values (@message)
|
||||
set @id = scope_identity()
|
||||
end
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.set_exception', N'P') is not null drop procedure dbo.set_exception
|
||||
go
|
||||
create procedure dbo.set_exception
|
||||
@database varchar(64),
|
||||
@procedure varchar(64),
|
||||
@message varchar(128),
|
||||
@parameters varchar(max) = null
|
||||
as begin
|
||||
|
||||
declare @procedure_id integer
|
||||
declare @message_id integer
|
||||
declare @exception_message varchar(max) = error_message()
|
||||
declare @exception_message_id integer
|
||||
declare @parameters_id integer
|
||||
|
||||
set nocount on
|
||||
|
||||
execute dbo.get_procedure @database, @procedure, @procedure_id output
|
||||
execute dbo.get_big_data @exception_message, @exception_message_id output
|
||||
execute dbo.get_big_data @parameters, @parameters_id output
|
||||
execute dbo.get_message @message, @message_id output
|
||||
|
||||
insert into dbo.Exceptions([procedure], [message], [parameters], exception, [status], code) values
|
||||
(@procedure_id, @message_id, @parameters_id, @exception_message_id, error_severity(), error_number())
|
||||
|
||||
end
|
||||
go
|
||||
|
||||
if object_id(N'dbo.ProceduresView', N'V') is not null drop view dbo.ProceduresView
|
||||
go
|
||||
create view dbo.ProceduresView as select
|
||||
procedures.id,
|
||||
databases.[name] as [database],
|
||||
procedures.[name] as [procedure],
|
||||
procedures.date_in,
|
||||
procedures.date_out
|
||||
from dbo.Procedures procedures
|
||||
join dbo.Databases databases on databases.id = procedures.[database]
|
||||
where
|
||||
procedures.date_out is null and
|
||||
databases.date_out is null
|
||||
go
|
||||
|
||||
if object_id(N'dbo.ExceptionsView', N'V') is not null drop view dbo.ExceptionsView
|
||||
go
|
||||
create view dbo.ExceptionsView as select
|
||||
exceptions.id,
|
||||
procedures.[database] as [database],
|
||||
procedures.[procedure] as [procedure],
|
||||
messages.[key] as [message],
|
||||
parameters.[value] as [parameters],
|
||||
exception.[value] as [exception],
|
||||
exceptions.[status],
|
||||
exceptions.code,
|
||||
exceptions.date_in
|
||||
from dbo.Exceptions exceptions
|
||||
join dbo.ProceduresView procedures on procedures.id = exceptions.[procedure]
|
||||
join dbo.Messages messages on messages.id = exceptions.[message]
|
||||
join dbo.BigData parameters on parameters.id = exceptions.parameters
|
||||
join dbo.BigData exception on exception.id = exceptions.exception
|
||||
where
|
||||
exceptions.date_out is null and
|
||||
procedures.date_out is null and
|
||||
messages.date_out is null and
|
||||
parameters.date_out is null and
|
||||
exception.date_out is null
|
||||
go
|
||||
Loading…
Reference in New Issue
Block a user