Compare commits

..

No commits in common. 'master' and 'liuyuyang_branch' have entirely different histories.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

@ -1,288 +0,0 @@
#include <iostream>
#include <thread>
#include <vector>
#include <map>
#include <mutex>
#include <atomic>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <cstring>
#define BUFFER_SIZE 1024
#define HTTP_SERVER_PORT 8080
std::vector<std::thread> threads; // 存储所有连接线程
std::map<int, int> sockets; // 存储套接字
std::mutex sockets_mutex; // 用于同步访问 sockets
std::atomic<bool> exit_flag(false); // 原子退出标志
// 维护连接的函数
void KeepConnection(int sock) {
char buffer[BUFFER_SIZE];
int nbytes;
while (!exit_flag) {
nbytes = recv(sock, buffer, BUFFER_SIZE, 0);
if (nbytes <= 0) {
std::cout << "Gateway disconnected" << std::endl;
break;
}
std::cout << "Received from gateway (Socket " << sock << "): " << buffer << std::endl;
}
{
std::lock_guard<std::mutex> lock(sockets_mutex);
sockets.erase(sock); // 从集合中移除套接字
}
close(sock);
}
// 连接到网关的函数
void ConnectToGateway(const std::string& ip, int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Could not create socket");
return;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) {
perror("Invalid address");
close(sock);
return;
}
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection to the server failed");
close(sock);
return;
}
{
std::lock_guard<std::mutex> lock(sockets_mutex);
sockets[sock] = 1; // 将套接字添加到集合中
}
std::cout << "Connected to gateway at " << ip << ":" << port << " (Socket " << sock << ")" << std::endl;
// 在新线程中维护连接
threads.emplace_back(KeepConnection, sock);
}
// 处理HTTP请求的函数
void HandleHttpRequest(int client_socket) {
char buffer[BUFFER_SIZE];
int bytes_read = recv(client_socket, buffer, sizeof(buffer), 0);
if (bytes_read <= 0) {
close(client_socket);
return;
}
// 简单解析HTTP请求
std::string http_request(buffer, bytes_read);
std::string ip;
int port;
// 寻找IP和端口号
auto host_pos = http_request.find("Host: ");
if (host_pos != std::string::npos) {
auto start = host_pos + std::string("Host: ").size();
ip = http_request.substr(start, http_request.find("\r\n", start) - start);
}
auto content_length_pos = http_request.find("Content-Length:");
if (content_length_pos != std::string::npos) {
auto start = content_length_pos + std::string("Content-Length: ").size();
int length = std::stoi(http_request.substr(start, http_request.find("\r\n", start) - start));
if (length > 0) {
char* content = new char[length];
bytes_read = recv(client_socket, content, length, 0);
if (bytes_read > 0) {
// 解析JSON内容假设前端发送的是JSON格式
// 这里需要添加JSON解析逻辑来提取IP和端口
// 示例:{"ip":"192.168.1.1","port":8080}
// 可以使用第三方库如nlohmann/json来解析JSON
// 假设解析后得到ip和port
// ConnectToGateway(ip, port);
delete[] content;
}
}
}
// 发送HTTP响应
std::string response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
send(client_socket, response.c_str(), response.size(), 0);
close(client_socket);
}
// 启动HTTP服务器的函数
void StartHttpServer() {
int http_server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (http_server_socket < 0) {
perror("Could not create HTTP server socket");
return;
}
int opt = 1;
if (setsockopt(http_server_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("Setsockopt failed");
close(http_server_socket);
return;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(HTTP_SERVER_PORT);
if (bind(http_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(http_server_socket);
return;
}
if (listen(http_server_socket, 5) < 0) {
perror("Listen failed");
close(http_server_socket);
return;
}
std::cout << "HTTP server listening on port " << HTTP_SERVER_PORT << std::endl;
while (!exit_flag) {
int client_socket = accept(http_server_socket, NULL, NULL);
if (client_socket < 0) {
perror("Accept failed");
continue;
}
threads.emplace_back(HandleHttpRequest, client_socket);
}
close(http_server_socket);
}
int main() {
// threads.emplace_back(StartHttpServer);
// std::string command, ip;
// int port;
// bool in_connect_mode = false;
// std::cout << "Enter command (connect/exit): ";
// while (true) {
// if (in_connect_mode)
// {
// std::cout << "continue connect or not ? (y or n) ";
// std::cin >> command;
// if(command=="y"){
// std::cout << "Enter the gateway IP address: ";
// std::cin >> ip;
// std::cout << "Enter the gateway port: ";
// std::cin >> port;
// ConnectToGateway(ip, port);
// }
// else {
// in_connect_mode = false; // 退出连接模式
// std::cout << "Exiting connect mode." << std::endl;
// }
// }
// else{
// std::cout << "Enter command (connect/exit): ";
// std::cin>>command;
// if (command == "connect") {
// if (in_connect_mode) {
// std::cout << "Already in connect mode." << std::endl;
// continue;
// }
// in_connect_mode = true; // 进入连接模式
// std::cout << "Enter the gateway IP address: ";
// std::cin >> ip;
// std::cout << "Enter the gateway port: ";
// std::cin >> port;
// ConnectToGateway(ip, port);
// } else if (command == "exit") {
// exit_flag = true; // 设置退出标志
// std::cout << "Exiting program." << std::endl;
// // 关闭所有套接字
// for (auto& sock_pair : sockets) {
// shutdown(sock_pair.first, SHUT_RDWR); // 关闭套接字的发送和接收
// close(sock_pair.first);
// }
// sockets.clear();
// std::cout << "sockets.clear" << std::endl;
// // 等待所有线程结束
// for (auto& thread : threads) {
// if (thread.joinable()) {
// thread.join();
// }
// }
// threads.clear();
// break; // 退出主循环
// } else {
// std::cout << "Unknown command" << std::endl;
// }
// }
// }
// std::cout<<"out"<<std::endl;
// return 0;
std::thread http_server_thread(StartHttpServer);
std::string command, ip;
int port;
bool in_connect_mode = false;
while (true) {
std::cout << "Enter command (connect/exit): ";
std::cin >> command;
if (command == "connect") {
if (in_connect_mode) {
std::cout << "Already in connect mode." << std::endl;
continue;
}
in_connect_mode = true;
std::cout << "Enter the gateway IP address: ";
std::cin >> ip;
std::cout << "Enter the gateway port: ";
std::cin >> port;
ConnectToGateway(ip, port);
} else if (command == "exit") {
break; // 接收到退出命令,退出主循环
} else {
std::cout << "Unknown command" << std::endl;
}
}
// 设置退出标志
exit_flag = true;
// 强制结束HTTP服务器线程
if (http_server_thread.joinable()) {
http_server_thread.join();
}
// 关闭所有套接字
for (auto& sock_pair : sockets) {
shutdown(sock_pair.first, SHUT_RDWR);
close(sock_pair.first);
}
sockets.clear();
// 等待所有工作线程结束
for (auto& thread : threads) {
if (thread.joinable()) {
thread.join();
}
}
threads.clear();
std::cout << "Exited program." << std::endl;
return 0;
}

@ -1,31 +0,0 @@
#include <iostream>
#include <mysql/mysql.h>
int main() {
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
std::cerr << "MySQL init failed" << std::endl;
return 1;
}
const char *server = "localhost";
const char *user = "rtsw";
const char *password = "123456";
const char *database = "nginxdb";
unsigned int port = 3306; // 使用云数据库提供的端口
if (mysql_real_connect(conn, server, user, password, database, port, NULL, 0) == NULL) {
std::cerr << "Connection error: " << mysql_error(conn) << std::endl;
mysql_close(conn);
return 1;
}
std::cout << "Successfully connected to the database" << std::endl;
// ... 执行数据库操作 ...
mysql_close(conn);
return 0;
}

@ -1,86 +0,0 @@
#include <iostream>
#include <thread>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define MAX_CLIENTS 5
#define BUFFER_SIZE 1024
// 声明 handle_client 函数
void handle_client(int client_socket);
int main() {
int server_fd, new_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
int opt = 1;
// 创建套接字
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置选项,允许重用地址
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt failed");
exit(EXIT_FAILURE);
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
// 绑定
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听
if (listen(server_fd, MAX_CLIENTS) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
std::cout << "Server listening on port " << PORT << std::endl;
while (true) {
client_len = sizeof(client_addr);
new_socket = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
if (new_socket < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
std::cout << "New client connected from " << inet_ntoa(client_addr.sin_addr) << " port " << ntohs(client_addr.sin_port) << std::endl;
// 创建并启动线程处理客户端
std::thread(handle_client, new_socket).detach();
}
close(server_fd);
return 0;
}
// 定义 handle_client 函数
void handle_client(int client_socket) {
while (true) {
char buffer[BUFFER_SIZE];
memset(buffer, 0, BUFFER_SIZE); // 清空缓冲区
int nbytes = read(client_socket, buffer, BUFFER_SIZE);
if (nbytes <= 0) {
std::cout << "Client disconnected." << std::endl;
close(client_socket);
break;
}
std::cout << "Received message from client: " << buffer << std::endl;
// 这里可以添加更多的处理逻辑
}
}

@ -1,66 +0,0 @@
#include <iostream>
#include <mysql/mysql.h>
int main() {
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
std::cerr << "MySQL init failed" << std::endl;
return 1;
}
const char *server = "localhost";
const char *user = "rtsw";
const char *password = "123456";
const char *database = "nginxdb";
unsigned int port = 3306;
if (mysql_real_connect(conn, server, user, password, database, port, NULL, 0) == NULL) {
std::cerr << "Connection error: " << mysql_error(conn) << std::endl;
mysql_close(conn);
return 1;
}
std::cout << "Successfully connected to the database" << std::endl;
// 插入数据
const char *insert_query = "INSERT INTO users (username, email) VALUES ('newuser', 'newuser@example.com')";
if (mysql_query(conn, insert_query)) {
std::cerr << "Insert error: " << mysql_error(conn) << std::endl;
} else {
std::cout << "Insert successful" << std::endl;
}
// 查询数据
const char *select_query = "SELECT * FROM users";
MYSQL_RES *result = mysql_store_result(conn);
if (result) {
MYSQL_ROW row;
while ((row = mysql_fetch_row(result))) {
std::cout << "id: " << row[0] << ", username: " << row[1] << ", email: " << row[2] << std::endl;
}
mysql_free_result(result);
} else {
std::cerr << "Select error: " << mysql_error(conn) << std::endl;
}
// 更新数据
const char *update_query = "UPDATE users SET email = 'newuser_updated@example.com' WHERE username = 'newuser'";
if (mysql_query(conn, update_query)) {
std::cerr << "Update error: " << mysql_error(conn) << std::endl;
} else {
std::cout << "Update successful" << std::endl;
}
// 删除数据
const char *delete_query = "DELETE FROM users WHERE username = 'newuser'";
if (mysql_query(conn, delete_query)) {
std::cerr << "Delete error: " << mysql_error(conn) << std::endl;
} else {
std::cout << "Delete successful" << std::endl;
}
mysql_close(conn);
return 0;
}

@ -1,280 +0,0 @@
#include "connector_controller.h"
#define BUFFER_SIZE 1024
#define HTTP_SERVER_PORT 8080
std::vector<std::thread> threads; // 存储所有连接线程
std::map<int, int> sockets; // 存储套接字
std::mutex sockets_mutex; // 用于同步访问 sockets
std::atomic<bool> exit_flag(false); // 原子退出标志
// 维护连接的函数
void KeepConnection(int sock) {
char buffer[BUFFER_SIZE];
int nbytes;
while (!exit_flag) {
nbytes = recv(sock, buffer, BUFFER_SIZE, 0);
if (nbytes <= 0) {
std::cout << "Gateway disconnected" << std::endl;
break;
}
std::cout << "Received from gateway (Socket " << sock << "): " << buffer << std::endl;
}
{
std::lock_guard<std::mutex> lock(sockets_mutex);
sockets.erase(sock); // 从集合中移除套接字
}
close(sock);
}
// 连接到网关的函数
void ConnectToGateway(const std::string& ip, int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Could not create socket");
return;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) {
perror("Invalid address");
close(sock);
return;
}
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection to the server failed");
close(sock);
return;
}
{
std::lock_guard<std::mutex> lock(sockets_mutex);
sockets[sock] = 1; // 将套接字添加到集合中
}
std::cout << "Connected to gateway at " << ip << ":" << port << " (Socket " << sock << ")" << std::endl;
// 在新线程中维护连接
threads.emplace_back(KeepConnection, sock);
}
// 处理HTTP请求的函数
void HandleHttpRequest(int client_socket) {
char buffer[BUFFER_SIZE];
int bytes_read = recv(client_socket, buffer, sizeof(buffer), 0);
if (bytes_read <= 0) {
close(client_socket);
return;
}
// 简单解析HTTP请求
std::string http_request(buffer, bytes_read);
std::string ip;
int port;
// 寻找IP和端口号
auto host_pos = http_request.find("Host: ");
if (host_pos != std::string::npos) {
auto start = host_pos + std::string("Host: ").size();
ip = http_request.substr(start, http_request.find("\r\n", start) - start);
}
auto content_length_pos = http_request.find("Content-Length:");
if (content_length_pos != std::string::npos) {
auto start = content_length_pos + std::string("Content-Length: ").size();
int length = std::stoi(http_request.substr(start, http_request.find("\r\n", start) - start));
if (length > 0) {
char* content = new char[length];
bytes_read = recv(client_socket, content, length, 0);
if (bytes_read > 0) {
// 解析JSON内容假设前端发送的是JSON格式
// 这里需要添加JSON解析逻辑来提取IP和端口
// 示例:{"ip":"192.168.1.1","port":8080}
// 可以使用第三方库如nlohmann/json来解析JSON
// 假设解析后得到ip和port
// ConnectToGateway(ip, port);
delete[] content;
}
}
}
// 发送HTTP响应
std::string response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
send(client_socket, response.c_str(), response.size(), 0);
close(client_socket);
}
// 启动HTTP服务器的函数
void StartHttpServer() {
int http_server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (http_server_socket < 0) {
perror("Could not create HTTP server socket");
return;
}
int opt = 1;
if (setsockopt(http_server_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("Setsockopt failed");
close(http_server_socket);
return;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(HTTP_SERVER_PORT);
if (bind(http_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(http_server_socket);
return;
}
if (listen(http_server_socket, 5) < 0) {
perror("Listen failed");
close(http_server_socket);
return;
}
std::cout << "HTTP server listening on port " << HTTP_SERVER_PORT << std::endl;
while (!exit_flag) {
int client_socket = accept(http_server_socket, NULL, NULL);
if (client_socket < 0) {
perror("Accept failed");
continue;
}
threads.emplace_back(HandleHttpRequest, client_socket);
}
close(http_server_socket);
}
/*
int main() {
// threads.emplace_back(StartHttpServer);
// std::string command, ip;
// int port;
// bool in_connect_mode = false;
// std::cout << "Enter command (connect/exit): ";
// while (true) {
// if (in_connect_mode)
// {
// std::cout << "continue connect or not ? (y or n) ";
// std::cin >> command;
// if(command=="y"){
// std::cout << "Enter the gateway IP address: ";
// std::cin >> ip;
// std::cout << "Enter the gateway port: ";
// std::cin >> port;
// ConnectToGateway(ip, port);
// }
// else {
// in_connect_mode = false; // 退出连接模式
// std::cout << "Exiting connect mode." << std::endl;
// }
// }
// else{
// std::cout << "Enter command (connect/exit): ";
// std::cin>>command;
// if (command == "connect") {
// if (in_connect_mode) {
// std::cout << "Already in connect mode." << std::endl;
// continue;
// }
// in_connect_mode = true; // 进入连接模式
// std::cout << "Enter the gateway IP address: ";
// std::cin >> ip;
// std::cout << "Enter the gateway port: ";
// std::cin >> port;
// ConnectToGateway(ip, port);
// } else if (command == "exit") {
// exit_flag = true; // 设置退出标志
// std::cout << "Exiting program." << std::endl;
// // 关闭所有套接字
// for (auto& sock_pair : sockets) {
// shutdown(sock_pair.first, SHUT_RDWR); // 关闭套接字的发送和接收
// close(sock_pair.first);
// }
// sockets.clear();
// std::cout << "sockets.clear" << std::endl;
// // 等待所有线程结束
// for (auto& thread : threads) {
// if (thread.joinable()) {
// thread.join();
// }
// }
// threads.clear();
// break; // 退出主循环
// } else {
// std::cout << "Unknown command" << std::endl;
// }
// }
// }
// std::cout<<"out"<<std::endl;
// return 0;
std::thread http_server_thread(StartHttpServer);
std::string command, ip;
int port;
bool in_connect_mode = false;
while (true) {
std::cout << "Enter command (connect/exit): ";
std::cin >> command;
if (command == "connect") {
if (in_connect_mode) {
std::cout << "Already in connect mode." << std::endl;
continue;
}
in_connect_mode = true;
std::cout << "Enter the gateway IP address: ";
std::cin >> ip;
std::cout << "Enter the gateway port: ";
std::cin >> port;
ConnectToGateway(ip, port);
} else if (command == "exit") {
break; // 接收到退出命令,退出主循环
} else {
std::cout << "Unknown command" << std::endl;
}
}
// 设置退出标志
exit_flag = true;
// 强制结束HTTP服务器线程
if (http_server_thread.joinable()) {
http_server_thread.join();
}
// 关闭所有套接字
for (auto& sock_pair : sockets) {
shutdown(sock_pair.first, SHUT_RDWR);
close(sock_pair.first);
}
sockets.clear();
// 等待所有工作线程结束
for (auto& thread : threads) {
if (thread.joinable()) {
thread.join();
}
}
threads.clear();
std::cout << "Exited program." << std::endl;
return 0;
}
*/

@ -1,22 +0,0 @@
#ifndef CONNECTOR_CONTROLLER_H
#define CONNECTOR_CONTROLLER_H
#include <iostream>
#include <thread>
#include <vector>
#include <map>
#include <mutex>
#include <atomic>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <cstring>
// 函数声明
void StartHttpServer();
void ConnectToGateway(const std::string& ip, int port);
void KeepConnection(int sock);
void HandleHttpRequest(int client_socket);
#endif // CONNECTOR_CONTROLLER_H

@ -1,68 +0,0 @@
/*
*/
/*
#include <iostream>
#include <mysql/mysql.h>
int main() {
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
std::cerr << "MySQL init failed" << std::endl;
return 1;
}
const char *server = "localhost";
const char *user = "rtsw";
const char *password = "123456";
const char *database = "nginxdb";
unsigned int port = 3306; // 使用云数据库提供的端口
if (mysql_real_connect(conn, server, user, password, database, port, NULL, 0) == NULL) {
std::cerr << "Connection error: " << mysql_error(conn) << std::endl;
mysql_close(conn);
return 1;
}
std::cout << "Successfully connected to the database" << std::endl;
// ... 执行数据库操作 ...
mysql_close(conn);
return 0;
}
*/
#include "connector_database.h"
// DatabaseOperation函数定义
void DatabaseOperation() {
MYSQL *conn = mysql_init(NULL);
if (conn == NULL) {
std::cerr << "MySQL init failed" << std::endl;
return;
}
const char *server = "localhost";
const char *user = "rtsw";
const char *password = "123456";
const char *database = "nginxdb";
unsigned int port = 3306;
if (mysql_real_connect(conn, server, user, password, database, port, NULL, 0) == NULL) {
std::cerr << "Connection error: " << mysql_error(conn) << std::endl;
mysql_close(conn);
return;
}
std::cout << "Successfully connected to the database" << std::endl;
// ... 执行数据库操作 ...
mysql_close(conn);
}

@ -1,10 +0,0 @@
#ifndef CONNECTOR_DATABASE_H
#define CONNECTOR_DATABASE_H
#include <iostream>
#include <mysql/mysql.h>
// 函数声明
void DatabaseOperation();
#endif // CONNECTOR_DATABASE_H

@ -1,35 +0,0 @@
#include <iostream>
#include <string>
#include "connector_controller.h"
#include "connector_database.h"
int main() {
std::string command;
bool running = true;
while (running) {
std::cout << "Enter command (start_http_server/connect_gateway/database_operation/exit): ";
std::cin >> command;
if (command == "start_http_server") {
StartHttpServer();
} else if (command == "connect_gateway") {
std::string ip;
int port;
std::cout << "Enter the gateway IP address: "<<std::endl;
std::cin>>ip; // 使用getline以获取包含空格的IP地址
std::cout << "Enter the gateway port: "<<std::endl;
std::cin >> port;
ConnectToGateway(ip, port);
} else if (command == "database_operation") {
DatabaseOperation();
} else if (command == "exit") {
running = false;
} else {
std::cout << "Unknown command" << std::endl;
}
}
std::cout << "Exiting program." << std::endl;
return 0;
}

@ -1,125 +0,0 @@
#include <iostream>
#include <thread>
#include <vector>
#include <map>
#include <mutex>
#include <atomic>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 1024
std::vector<std::thread> threads; // 存储所有连接线程
std::map<int, int> sockets; // 存储套接字
std::mutex sockets_mutex; // 用于同步访问 sockets
std::atomic<bool> exit_flag(false); // 原子退出标志
// 维护连接的函数
void KeepConnection(int sock) {
char buffer[BUFFER_SIZE];
int nbytes;
while (!exit_flag) {
nbytes = recv(sock, buffer, BUFFER_SIZE, 0);
if (nbytes <= 0) {
std::cout << "Gateway disconnected" << std::endl;
break;
}
std::cout << "Received from gateway (Socket " << sock << "): " << buffer << std::endl;
}
{
std::lock_guard<std::mutex> lock(sockets_mutex);
sockets.erase(sock); // 从集合中移除套接字
}
close(sock);
}
// 连接到网关的函数
void ConnectToGateway(const std::string& ip, int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Could not create socket");
return;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) {
perror("Invalid address");
close(sock);
return;
}
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection to the server failed");
close(sock);
return;
}
{
std::lock_guard<std::mutex> lock(sockets_mutex);
sockets[sock] = 1; // 将套接字添加到集合中
}
std::cout << "Connected to gateway at " << ip << ":" << port << " (Socket " << sock << ")" << std::endl;
// 在新线程中维护连接
threads.emplace_back(KeepConnection, sock);
}
int main() {
std::string command, ip;
int port;
bool in_connect_mode = false;
while (true) {
std::cout << "Enter command (connect/exitconnect/exit): ";
std::cin >> command;
if (command == "connect") {
if (in_connect_mode) {
std::cout << "Already in connect mode." << std::endl;
continue;
}
in_connect_mode = true; // 进入连接模式
std::cout << "Enter the gateway IP address: ";
std::cin >> ip;
std::cout << "Enter the gateway port: ";
std::cin >> port;
ConnectToGateway(ip, port);
} else if (command == "exitconnect") {
if (!in_connect_mode) {
std::cout << "Not in connect mode." << std::endl;
continue;
}
in_connect_mode = false; // 退出连接模式
std::cout << "Exiting connect mode." << std::endl;
} else if (command == "exit") {
exit_flag = true; // 设置退出标志
std::cout << "Exiting program." << std::endl;
// 关闭所有套接字
for (auto& sock_pair : sockets) {
shutdown(sock_pair.first, SHUT_RDWR); // 关闭套接字的发送和接收
close(sock_pair.first);
}
sockets.clear();
// 等待所有线程结束
for (auto& thread : threads) {
if (thread.joinable()) {
thread.join();
}
}
threads.clear();
break; // 退出主循环
} else {
std::cout << "Unknown command" << std::endl;
}
}
return 0;
}

@ -1,3 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (G:)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PackageRequirementsSettings">
<option name="requirementsPath" value="" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="EPYTEXT" />
<option name="myDocStringFormat" value="Epytext" />
</component>
</module>

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (controller)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (G:)" project-jdk-type="Python SDK" />
</project>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/controller.iml" filepath="$PROJECT_DIR$/.idea/controller.iml" />
</modules>
</component>
</project>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

@ -1,11 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: confControl.py
# @time: 2024/6/21 11:18
# @desc:
#TODO 通过ssh在线更改nginx的conf文件

@ -1,378 +0,0 @@
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: DatabaseOp.py
# @time: 2024/6/19 9:22
# @desc:
import mysql
from mysql.connector import Error
# 连接数据库函数
def connect_user_db():
"""
@author: 原凯峰
@return:
"""
try:
conn = mysql.connector.connect(
host="localhost",
user="rtsw",
password="123456",
database="nginxdb",
port=3306
)
if conn.is_connected():
return conn
except Error as e:
print("Connection error:", e)
# 插入用户数据函数
def insert_user_data(conn, username, real_name, ID, password, tel):
"""
@author: 原凯峰
@param conn:
@param username:
@param real_name:
@param ID:
@param password:
@param tel:
@return:
"""
try:
cursor = conn.cursor()
query = """
INSERT INTO user (username, real_name, ID, password, tel)
VALUES (%s, %s, %s, %s, %s)
"""
cursor.execute(query, (username, real_name, ID, password, tel))
conn.commit()
return cursor.lastrowid
except Error as e:
print("Insert error:", e)
# 搜索是否存在某用户
def select_user_data(conn,username,ID):
"""
@author: 原凯峰
@param conn:
@param username:
@param ID:
@return:
"""
try:
cursor = conn.cursor()
select_query = "SELECT * FROM user"
cursor.execute(select_query)
for row in cursor.fetchall():
print("id: {}, username: {}, email: {}".format(row[0], row[1], row[2]))
except Error as e:
print("Select error:", e)
# 查询用户函数
def select_exist_user(conn, username):
"""
@author: 原凯峰
@param conn:
@param username:
@return:
"""
try:
cursor = conn.cursor()
# 构造查询语句确保使用参数化查询以防止SQL注入
select_query = "SELECT * FROM user WHERE username = %s"
cursor.execute(select_query, (username,))
# 使用fetchall()来获取所有结果
results = cursor.fetchall()
# 如果结果不为空,则表示找到了匹配的用户名
if results:
for row in results:
print("id: {}, username: {}, email: {}".format(row[0], row[1], row[2]))
return True
else:
return False
except Error as e:
print("Select error:", e)
return False
# 更新用户信息函数
def update_user(conn, username, new_email):
"""
@author: 原凯峰
@param conn:
@param username:
@param new_email:
@return:
"""
try:
cursor = conn.cursor()
query = """
UPDATE users SET email = %s WHERE username = %s
"""
cursor.execute(query, (new_email, username))
conn.commit()
return cursor.rowcount
except Error as e:
print("Update error:", e)
# 删除用户函数
def delete_user(conn, username):
"""
@author: 原凯峰
@param conn:
@param username:
@return:
"""
try:
cursor = conn.cursor()
delete_query = """
DELETE FROM users WHERE username = %s
"""
cursor.execute(delete_query, (username,))
conn.commit()
return cursor.rowcount
except Error as e:
print("Delete error:", e)
# ************************server部分***************************** #
# 判断是否存在数据库中已经收录过这个服务器
def is_exist_server(conn, server_name):
"""
@todo 查询该服务器是否已经被servers数据库收录
@param conn:
@param server_name:
@return:
"""
try:
cursor = conn.cursor()
# 构造查询语句确保使用参数化查询以防止SQL注入
select_query = "SELECT * FROM servers WHERE server_name = %s"
cursor.execute(select_query, (server_name,))
# 使用fetchall()来获取所有结果
results = cursor.fetchall()
# 如果结果不为空,则表示找到了匹配的用户名
if results:
for row in results:
print("server_name: {}, status: {}".format(row[0], row[1]))
return True
else:
return False
except Error as e:
print("Select error:", e)
return False
# 将这一次的服务器活跃信息存放到服务器中,是第一次存放
def insert_server_data(conn,server_name,status,upstream,detect_date,responseTime,protocol):
"""
@param conn:
@param server_name:
@param status:
@param upstream:
@param detect_date:
@param responseTime:
@param protocol:
@return:
"""
try:
cursor = conn.cursor()
query = """
INSERT INTO servers (server_name, status, upstream, detect_date, responseTime, protocol)
VALUES (%s, %s, %s, %s, %s, %s)
"""
cursor.execute(query, (server_name, status, upstream, detect_date, responseTime, protocol))
conn.commit()
return cursor.lastrowid
except Error as e:
print("Insert error:", e)
# 在第n次获得这个服务器的信息时更改服务器列表中的信息
def update_server_list(conn,server_name, status, upstream, detect_date, responseTime, protocol):
"""
@todo 将服务器信息填入或者更改在服务器列表中
@return:
"""
# 更新的数据和条件
update_data = {
'status': f'{status}', # 需要更新的列和新值
'responseTime': f'{responseTime}',
'detect_date': f'{detect_date}',
'upstream': f'{upstream}',
'protocol': f'{protocol}',
# 可以添加更多的列和值
}
where_condition = f'server_name = {server_name}' # 定位记录的条件例如主键ID为1的记录
# 连接到数据库
try:
cursor = conn.cursor()
# 构建UPDATE语句
update_columns = ', '.join([f"{key} = %s" for key in update_data.keys()])
update_values = tuple(update_data.values())
# sql_update_query = f"UPDATE servers SET {update_columns} WHERE {where_condition}"
# 采用下面这个方法不会出错
sql_update_query = "UPDATE servers SET status = %s, responseTime = %s, detect_date = %s, upstream = %s, protocol = %s WHERE server_name = %s"
update_values = (status, responseTime, detect_date, upstream, protocol, server_name)
# 执行UPDATE语句
cursor.execute(sql_update_query, update_values)
# 提交事务
conn.commit()
# 打印受影响的行数
print(cursor.rowcount, "record(s) updated.")
except Error as e:
print("Error while updating data to MySQL", e)
# 获取服务器列表中的所有服务器的信息
def select_server_health_list(conn):
"""
TODO 获得目前数据库中所有的服务器名称返回一个数组
@author: 原凯峰
@param conn:
@return: 存放有服务器名称的数组
"""
sql_query ="SELECT * FROM servers"
cursor = conn.cursor()
# 执行查询语句
cursor.execute(sql_query)
# 获取所有查询结果
rows = cursor.fetchall()
# 将查询结果转换为字典列表
columns = [i[0] for i in cursor.description] # 获取列名
data_list = [dict(zip(columns, row)) for row in rows] # 将每行数据转换为字典
return data_list
def insert_serverhealthlog_data(conn,server_name,status,upstream,detect_date,responseTime,protocol):
"""
@param conn:
@param server_name:
@param status:
@param upstream:
@param detect_date:
@param responseTime:
@param protocol:
@return:
"""
try:
cursor = conn.cursor()
query = """
INSERT INTO serverhealthlog (server_name, status, upstream, detect_date, responseTime, protocol)
VALUES (%s, %s, %s, %s, %s, %s)
"""
cursor.execute(query, (server_name, status, upstream, detect_date, responseTime, protocol))
conn.commit()
return cursor.lastrowid
except Error as e:
print("Insert error:", e)
def select_server_health_log(conn,servername):
"""
#TODO 查询某个服务器的历史健康状态的多条数据需要查询ServerHealthLog表,这个查询时间的范围还需要确定
@author: 原凯峰
@param conn:
@param servername:
@return:返回值是一个字典列表
"""
sql_query = f"SELECT * FROM serverhealthlog WHERE server_name = '{servername}'"
cursor = conn.cursor()
# 执行查询语句
cursor.execute(sql_query)
# 获取所有查询结果
rows = cursor.fetchall()
# 将查询结果转换为字典列表
# 假设你的表有列名为'id', 'name', 'age'等
columns = [i[0] for i in cursor.description] # 获取列名
data_list = [dict(zip(columns, row)) for row in rows] # 将每行数据转换为字典
return data_list
def delete_server_health_log(conn,servername,finaldata):
"""
@todo 删除某个服务器某段时间之前的健康信息
@author: 原凯峰
@param conn: 数据库连接
@param servername: 服务器呢名称
@param finaldata: 从哪个日期之前的数据都要删除
@return:
"""
# 通过日期获得当日日志数量
def getLogNumByDate(conn,date):
"""
@param conn:
@param date:
@return:
"""
cursor = conn.cursor()
wherequery = f"detect_date = '{date}'"
query = f"SELECT COUNT(*) FROM serverhealthlog WHERE {wherequery}"
# print(query)
cursor.execute(query)
count = cursor.fetchone()[0]
# 关闭连接
cursor.close()
return count
# 测试用例
def test():
conn = connect_user_db()
date = '2024-6-2'
print(getLogNumByDate(conn,date))
# test()
# 断开数据库连接函数
def disconnect_db(conn):
"""
@author: 原凯峰
@param conn:
@return:
"""
if conn.is_connected():
cursor = conn.cursor()
cursor.close()
conn.close()
print("Database connection closed.")
# 示例使用
# if __name__ == "__main__":
# # 连接数据库
# conn = connect_user_db()
# if conn:
# # 插入用户数据
# insert_user_data(conn, 'username1', 'real_name1', 'ID1', 'password1', 'tel1')
#
# # 查询用户
# select_users(conn)
#
# # 更新用户信息
# # update_user(conn, 'username1', 'new_email1')
#
# # 删除用户
# # delete_user(conn, 'username1')
#
# # 断开数据库连接
# disconnect_db(conn)

@ -1,83 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: MachineLearningDivider.py
# @time: 2024/6/26 8:21
# @desc:利用随机森林法进行模型训练,能够通过平均响应时间、故障率等数据计算出服务器的健康状态
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, accuracy_score
import pickle
def trainmodel():
# 假设我们有以下数据集
X = [
[0.3, 0.005], # 服务器特征:平均响应时间和故障率
[2.5, 0.03],
[0.7, 0.045],
[1.2, 0.002],
[3.5, 0.1],
[1.3, 0.05],
[0.01, 0.15], # 服务器特征:平均响应时间和故障率
[5, 0.03],
[0.7, 0.015],
[1.4, 0.02],
[0.15, 0.2],
[1.3, 0.005],
]
y = ['良好', '一般', '一般', '良好', '', '一般', '一般', '', '良好', '', '', '良好'] # 对应的健康状态标签
# 将健康状态标签转换为数值
label_mapping = {'一般': 0, '良好': 1, '': 2}
y_encoded = [label_mapping[label] for label in y]
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y_encoded, test_size=0.4, random_state=42)
# 选择模型,这里使用随机森林分类器
model = RandomForestClassifier(n_estimators=100, random_state=42)
# 训练模型
model.fit(X_train, y_train)
# 预测测试集
y_pred = model.predict(X_test)
# 评估模型
print(classification_report(y_test, y_pred))
print("Accuracy:", accuracy_score(y_test, y_pred))
# 保存模型
with open('server_health_model.pkl', 'wb') as file:
pickle.dump(model, file)
# trainmodel()
# 定义一个函数来加载模型并进行预测
def load_model_and_predict(new_data):
with open('../LogAnalyze/server_health_model.pkl', 'rb') as file:
loaded_model = pickle.load(file)
predictions = loaded_model.predict(new_data)
return predictions
# 定义一个函数来将预测结果转换为健康等级
def predict_health_status(new_data):
label_mapping = {'一般': 0, '良好': 1, '': 2}
predictions = load_model_and_predict(new_data)
# 创建逆向映射字典
inverse_label_mapping = {value: key for key, value in label_mapping.items()}
# 使用逆向映射字典转换预测结果
health_status = [inverse_label_mapping[pred] for pred in predictions]
return health_status
# 测试函数
def testcase():
new_data = [[0.4, 0.01]] # 新的服务器数据
health_status = predict_health_status(new_data)
print("预测的健康状态:", health_status)
# testcase()

@ -1,59 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: ServerHealthLogAnalyzer.py
# @time: 2024/6/20 16:57
# @desc: 用于对服务器健康信息的数据分析和日志信息的数据分析
from DbProcessor.DatabaseOp import *
class ServerHealthLogAnalyzer():
def __init__(self):
self.serverList = select_server_health()
self.analyzeReturn = self.returnMessageProvider()
def returnMessageProvider(self):
"""
@todo 能够将每一个服务器的日志分析结果存放进dict中方便后续使用
@author: 原凯峰
@return: 存放有服务器健康状态分析的字典
"""
serverHealthDict = {}
for serverName in self.serverList:
aba= self.logAnalyzer(serverName)
return serverHealthDict
def logAnalyzer(self,serverName):
"""
@todo 需要处理日志信息并且将日志信息进行处理形成一个统计性的结论似乎可以借助某些在线应用的api来辅助进行日志分析
@author: 原凯峰
@param serverName:
@return: 存有分析结果的字符串
"""
serverHealthLog = select_server_health_log(serverName)
analyzeResult = ""
return analyzeResult
"""
可能可以做的数据分析
故障率
存活率
周期性存活率
平均正常运行时间
平均故障时间
已经正常/故障运行的时间
"""

@ -1,60 +0,0 @@
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 测试样例数据
data = {
'server_name': ['Server1', 'Server1', 'Server2', 'Server2',
'Server1', 'Server1', 'Server2', 'Server2'],
'check_time': ['2024-03-01 10:00', '2024-03-01 11:00', '2024-03-31 12:00',
'2024-04-15 13:00', '2024-06-01 14:00', '2024-06-30 15:00',
'2024-12-25 16:00', '2024-12-31 17:00'],
'status': ['Normal', 'Error', 'Normal', 'Warning',
'Normal', 'Error', 'Warning', 'Normal']
}
# 创建DataFrame
df = pd.DataFrame(data)
df['check_time'] = pd.to_datetime(df['check_time'])
# 添加季节性、月度、周度、日度和小时特征
df['season'] = df['check_time'].dt.to_period('Q').astype(str)
df['month'] = df['check_time'].dt.month_name()
df['day_of_week'] = df['check_time'].dt.day_name()
df['day'] = df['check_time'].dt.day
df['hour'] = df['check_time'].dt.hour
# 定义服务器存活状态
df['is_failure'] = df['status'].apply(lambda x: 1 if x not in ['Normal'] else 0)
# 按时间粒度分组并计算故障次数和总检查次数
grouped = df.groupby(['server_name', 'season', 'month', 'day_of_week', 'day', 'hour'])['is_failure'].agg(Total='sum').reset_index()
# 计算故障率
grouped['failure_rate'] = grouped['Total'] / grouped.groupby(['server_name', 'season', 'month', 'day_of_week', 'day', 'hour']).cumcount() + 1
# 为了可视化我们使用pivot来重塑数据
pivot_season = grouped.pivot_table(index=['server_name', 'season'], columns='hour', values='failure_rate', fill_value=0)
pivot_month = grouped.pivot_table(index=['server_name', 'month'], columns='day_of_week', values='failure_rate', fill_value=0)
pivot_week = grouped.pivot_table(index=['server_name', 'day_of_week'], columns='day', values='failure_rate', fill_value=0)
pivot_day = grouped.pivot_table(index=['server_name', 'day'], columns='hour', values='failure_rate', fill_value=0)
# 可视化季节性故障率
sns.heatmap(pivot_season, annot=True, cmap='YlGnBu')
plt.title('Seasonal Failure Rates by Server and Hour')
plt.show()
# 可视化月度故障率
sns.heatmap(pivot_month, annot=True, cmap='YlGnBu')
plt.title('Monthly Failure Rates by Server and Day of Week')
plt.show()
# 可视化周度故障率
sns.heatmap(pivot_week, annot=True, cmap='YlGnBu')
plt.title('Weekly Failure Rates by Server and Day')
plt.show()
# 可视化日度故障率
sns.heatmap(pivot_day, annot=True, cmap='YlGnBu')
plt.title('Daily Failure Rates by Server and Hour')
plt.show()

@ -1,86 +0,0 @@
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: BackendProcessor.py
# @time: 2024/6/19 9:22
# @desc:
from DbProcessor.DatabaseOp import *
import LogAnalyze.ServerHealthLogAnalyzer as Analyzer
import json
#TODO 还没写
class BackendProcessor():
def __init__(self,receivedMessage):
self.receivedMessage = receivedMessage
self.messageType = self.getreceivedMessageType()
self.returnMessage = self.dataProcessor()
def getreceivedMessageType(self):
"""
@author: 原凯峰
@return: messageType
"""
try:
# 由于后端json中涉及到“type”字段所以采用kind作为关键词
messageType = self.receivedMessage["kind"]
print(f"this is a {messageType} message")
return messageType
except Exception as e:
print(f"An error occurred: {e}")
# 进行错误处理,比如记录日志或者设置默认值
return None
def dataProcessor(self):
"""
@author: 原凯峰
@return:
"""
# 如果是登录信息
if self.messageType == "server_health_list":
serverNum, serverList = self.serverHealthMessageParser(self.receivedMessage)
conn = connect_user_db()
for serverInfo in serverList:
# 需要填入数据库的消息
server_name =serverInfo["name"]
upstream = serverInfo["upstream"]
status = 0
if serverInfo["status"] == 'up':
status = 1
detect_date = serverInfo["last_check_time"]#TODO 这个字段和下面这个字段都需要后续修改名字。
responseTime = serverInfo["last_response_time"]#
protocol = serverInfo["type"]
# 先判断是否该服务器已经存在;
if not is_exist_server(conn, server_name):
insert_server_data(conn,server_name, status, upstream, detect_date, responseTime, protocol)
returnMessage = " success!"
else:
update_server_list(conn,server_name, status, upstream, detect_date, responseTime, protocol)
returnMessage = "Server already exists. "
insert_serverhealthlog_data(conn,server_name,status,upstream,detect_date,responseTime,protocol)
def serverHealthMessageParser(self,serversHealthList):
"""
@param serversHealthList: 包含有服务器健康信息的json
@return:serverList ,存放有服务器健康状态的数组
"""
try:
servers = serversHealthList["servers"]
num = servers["total"]
serverList = servers["server"]
return num, serverList
except Exception as e:
print("find an error while parsing server health list!!")
return 0,[]
def backendTest():
json_str = '{"source": "backend", "kind": "server_health_list", "servers": {"total":2,"generation":1, "server":[{"index":0,"type":"tcp","last_response_time":"30","name":"1.205.204.0","status":"up","upstream":"cluster","last_check_time":"2024-6-5"}]}}'
data_dict = json.loads(json_str)
a = BackendProcessor(data_dict)
# backendTest()

@ -1,378 +0,0 @@
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: FrontendProcessor.py
# @time: 2024/6/19 9:22
# @desc:
from DbProcessor.DatabaseOp import *
from LogAnalyze import MachineLearningDivider as mldivider
from datetime import datetime, timedelta
import json
class FrontendProcessor():
def __init__(self,receivedMessage):
self.receivedMessage = receivedMessage
self.messageType = self.getreceivedMessageType()
self.returnMessage = self.dataProcessor()
def getreceivedMessageType(self):
"""
@author: 原凯峰
@return: messageType
"""
try:
messageType = self.receivedMessage["type"]
print(f"this is a {messageType} message")
return messageType
except Exception as e:
print(f"An error occurred: {e}")
# 进行错误处理,比如记录日志或者设置默认值
return None
def dataProcessor(self):
"""
@disc: 这个函数是这个类的核心处理函数处理来自前端的所有请求并且返回响应信息
@author: 原凯峰
@return:
"""
# 如果是登录信息
if self.messageType == "register_message":
conn = connect_user_db()
# 需要填入数据库的消息
username = self.receivedMessage["username"]
password = self.receivedMessage["password"]
real_name = self.receivedMessage["real_name"]
ID = self.receivedMessage["ID"]
tel = self.receivedMessage["tel"]
# 先判断是否改用户已经存在;
if not select_exist_user(conn,username):
insert_user_data(conn,username,real_name,ID,password,tel)
returnMessage = "RegistOP success!"
return returnMessage
else:
returnMessage = "Username already exists or Database error. "
return returnMessage
elif self.messageType == "getallserverstatus":
# 获取所有服务器的状态信息,主要用于服务器列表界面的展示
return self.getAllServerStatus()
elif self.messageType == "getserverinfo_message":
# 获取某个服务器的某些数据,故障率、平均响应时间等,
serverName = self.receivedMessage["server_name"]
serverInfo = self.getServerInfo(serverName)
return serverInfo
elif self.messageType == "get_overall_message":
overAllMessage = self.caculateOverallMessage()
return overAllMessage
elif self.messageType == "get_net_point_message":
# 前端像我请求网络环境中的所有信息
backMessage=self.getNetPointInfo()
# self.returnMessage == f"{backMessage}"
elif self.messageType == "alt_backend_config":
# 下面这个判断用于接收并且处理前端传输过来的更改后端配置文件的请求。
# TODO这个函数的实现可能可以采用以下这种实现方式向后端发送更改信息 不着急写
"""
@想法 是否可以采用ssh远程操控 或者说仅仅担任一个消息中转的作用
@疑惑是否需要建立一个记录这个更改操作的数据库表名为 altconfighistory
"""
conn = connect_user_db()
# 需要填入数据库的消息
username = self.receivedMessage["username"]
password = self.receivedMessage["password"]
json_example = '{"source":"backend","config":"this is a test config file"} '
def getNetPointInfo(self):
"""
@todo 获取当前网络节点所有的节点信息这个不着急写
@return: 所需要的信息字段
"""
rez = '{"servers":"{[{"name":"one","status":"alive","ip":"192.168.0.0.132:8080"},{"name":"one","status":"alive","ip":"192.168.0.0.132:8080"}]}", "gateways":"{["name":"gateway1",abc]}"}'
return rez
def getServerInfo(self,serverName):
"""
@date6.25 14:58
@param serverName:
@return: 返回统计好的服务器的基本信息
"""
conn = connect_user_db()
serverHealthLog = select_server_health_log(conn,serverName)
ResponseTimeList = []
DisabledTime = 0
AbledTime = 0
logNum = len(serverHealthLog)
DetectTimeList = []
# 遍历每一条数据
for serverlog in serverHealthLog:
# 判断该条数据中该服务器是否存活
if serverlog["status"] == '1':
AbledTime += 1
else:
DisabledTime += 1
serverlog.pop('status')
serverlog.pop('server_name')
serverlog.pop('protocol')
serverlog.pop('health_id')
serverlog.pop('upstream')
ResponseTimeList.append(int(serverlog["responseTime"]))
DetectTimeList.append(serverlog['detect_date'])
print(ResponseTimeList)
# 故障率
DisabledRate = float(DisabledTime)/(DisabledTime + AbledTime)
# 响应时间类的统计数据
AverageResponseTime = sum(ResponseTimeList)/float(logNum)
MinResponseTime = min(ResponseTimeList)
MaxResponseTime = max(ResponseTimeList)
stats = {
"servername": serverName,
"DisabledRate": DisabledRate,
"AverageResponseTime": AverageResponseTime,
"MinResponseTime": MinResponseTime,
"MaxResponseTime": MaxResponseTime,
"ResponseTimeArray": ResponseTimeList,
"Time": DetectTimeList
}
# 使用json.dumps将字典转换为JSON格式的字符串
backMessage = json.dumps(stats)
return backMessage
def getAllServerStatus(self):
"""
给列表页返回信息
@return:
"""
conn = connect_user_db()
allServerStatusList = select_server_health_list(conn)
for ServerStatus in allServerStatusList:
ServerStatus.pop('upstream')
if ServerStatus['status'] == '1':
ServerStatus['status'] = '存活'
else:
ServerStatus['status'] = '死亡'
ServerStatus['address'] = self.queryIpLocation(ServerStatus['server_name'])
return allServerStatusList
def queryIpLocation(self, ip_address):
"""
@disc: 返回IP的所在地
@param ip_address:
@return:
"""
ip_data_file = '../china_ip_address.txt'
result = None
with open(ip_data_file, 'r', encoding='utf-8') as f:
for line in f:
if line.strip(): # 确保行非空
parts = line.split()
if len(parts) >= 3:
start_ip = parts[0]
end_ip = parts[1]
location_info = ' '.join(parts[2:])
if ip_address >= start_ip and ip_address <= end_ip:
result = location_info.split('')[1].strip() # 获取中国的地区信息
break
return result
def caculateOverallMessage(self):
"""
@todo 计算服务器的地区分布并且获得统计性数据 利用机器学习算法计算服务器的存活程度 计算平均存活率
@return:返回包含以上所有数据的json格式数据
"""
conn = connect_user_db()
serverList = select_server_health_list(conn)
print(serverList)
provinceDict = {}
healthDict= {}
healthCnt = 0 # 统计总服务器列表中的健康状态信息,设计所有的服务器,而不是某个服务器的将抗日志统计
# 前端总揽界面所需要的前三个服务器的七天内的序列数据直接通过重用类中本身就有的getServerInfo函数进行获取
datasets = []#todo
# 以后考虑把这几个字段放在数据库里,入库的时候就算好
cnt = 3
for serverInfo in serverList:
province = self.queryIpLocation(serverInfo['server_name'])
disableRate = self.getDisabledRate(conn,serverInfo['server_name'])
avgReponsetime = self.getAvgResponseTime(conn,serverInfo['server_name'])[0]
if cnt:
server_dict = json.loads(self.getServerInfo(serverInfo['server_name']))
timeArray = server_dict['ResponseTimeArray']
length = min(6,len(timeArray))
parse_server_dict = {
'label': serverInfo['server_name'],
'data' : timeArray[:length]
}
datasets.append(parse_server_dict)
cnt -= 1
# 处理健康情况信息
if int(serverInfo['status']):
healthCnt += 1
# 处理省份信息
if province in provinceDict:
tmp = provinceDict[province]
provinceDict[province] = tmp+1 #计数加一
else:
provinceDict[province] = 1
# 存活度信息
testdata = [[avgReponsetime/1000, disableRate]]
health = mldivider.predict_health_status(testdata)[0]
# 处理存活度信息
if health in healthDict:
tmp = healthDict[health]
healthDict[health] = tmp+1 #计数加一
else:
healthDict[health] = 1
provinceDistribution = self.getDictRate(provinceDict,len(serverList))
healthDistribution = self.getDictRate(healthDict,len(serverList))
overallHealthRate = float(healthCnt)/len(serverList)
# 日志统计数据
dateArray, logNumArray = self.getLogNumOnDate(conn)
datadict = {
'labels':['周一','周二','周三','周四','周五','周六','周日'],
'datasets':datasets
}
overallMessage = {
'AveSurRate': overallHealthRate,
'TimeArray': dateArray,
'DataArray': logNumArray,
'data1': provinceDistribution,
'data2': healthDistribution,
'data': datadict
}
return overallMessage
def getLogNumOnDate(self,conn):
"""
从数据库中获取关于服务器健康状态的日志信息返回结果为每一天的日志信息数量这里的时间格式需要进行自己的定义
@param conn:
@return: 可以用于建立柱形图的信息
"""
dateArray = []
logNumArray = []
# 定义时间格式
date_format = "%Y-%m-%d"
# 计算当前日期之前15天的日期
for day in range(1,16):
delta = timedelta(days=-day)
previous_date = (datetime.now() + delta).strftime(date_format)
# 去除前导零
previous_date = previous_date.replace("-0", "-")
dateArray.append(previous_date)
logNum = getLogNumByDate(conn,previous_date)
logNumArray.append(logNum)
return dateArray, logNumArray
def getDisabledRate(self,conn,serverName):
"""
@disc 为了更加方便调用把这个功能单独拿出来
@param serverName:
@return: 返回故障率
"""
serverHealthLog = select_server_health_log(conn, serverName)
DisabledTime = 0
AbledTime = 0
# 遍历每一条数据
for serverlog in serverHealthLog:
# 判断该条数据中该服务器是否存活
if serverlog["status"] == '1':
AbledTime += 1
else:
DisabledTime += 1
# 故障率
DisabledRate = float(DisabledTime) / (DisabledTime + AbledTime)
return DisabledRate
def getAvgResponseTime(self,conn,serverName):
"""
获取某个服务器的平均响应时间
@param serverName:
@return:
"""
serverHealthLog = select_server_health_log(conn, serverName)
ResponseTimeList = []
logNum = len(serverHealthLog)
DetectTimeList = []
# 遍历每一条数据
for serverlog in serverHealthLog:
# 判断该条数据中该服务器是否存活
ResponseTimeList.append(int(serverlog["responseTime"]))
DetectTimeList.append(serverlog['detect_date'])
# 响应时间类的统计数据
AverageResponseTime = sum(ResponseTimeList) / float(logNum)
MinResponseTime = min(ResponseTimeList)
MaxResponseTime = max(ResponseTimeList)
return (AverageResponseTime, MinResponseTime, MaxResponseTime)
def getDictRate(self, Dict, num):
"""
返回比率
@param dict:
@return:
"""
ret = []
for key in Dict.keys():
rateDict = {}
rateDict['value'] = Dict[key]/float(num)
rateDict['name'] = key
ret.append(rateDict)
return ret
def test_case_serverinfo():
di = {"source":"frontend" , "type": "getserverinfo_message","server_name":"1.205.204.0"}
a = FrontendProcessor(di)
print(a.returnMessage)
def test_case_serverlist():
di = {"source":"frontend" , "type": "getallserverstatus"}
a = FrontendProcessor(di)
print(a.returnMessage)
def test_case_overallMessage():
di = {"source":"frontend" , "type": "get_overall_message"}
a = FrontendProcessor(di)
print(a.returnMessage)
# test_case_serverlist()
# test_case_serverinfo()
test_case_overallMessage()

@ -1,59 +0,0 @@
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: PreDataProcessor.py
# @time: 2024/6/19 9:22
# @desc:
import json
from MessageHandler.FrontendProcessor import FrontendProcessor
from MessageHandler.BackendProcessor import BackendProcessor
class preDataProcessor():
def __init__(self,rawData):
self.rawData = rawData
self.processedData = self.preDataProcess()
self.returnMessage = self.todo()
def preDataProcess(self):
"""
@author: 原凯峰
@return:processedData处理过后的数据
@todo 前端可以用这个但是后端不太能用
"""
print("preDataProcessing")
processedData = parseJsonToDict(self.rawData)
return processedData
def todo(self):
"""
@author: 原凯峰
@return:前后端信息处理模块的返回信息
"""
if self.processedData["source"]=="frontend":
print("this is a frontend message")
frontProsece = FrontendProcessor(self.processedData)
return frontProsece.returnMessage
elif self.processedData["source"]=="backend":
#对于网关信息的处理
print("this is a backend message")
backendProcess = BackendProcessor(self.processedData)
#这个信息只是一个能够拿到种类的深度,如果想要活得更都的数据,需要在后端信息处理模块里面进行深度解包
return backendProcess.returnMessage
def parseJsonToDict(json_data):
"""
@author: 原凯峰
@param json_data:
@return: 将json信息解析厚的字典
"""
try:
# 使用json.loads()方法将JSON字符串解析为字典
data_dict = json.loads(json_data)
return data_dict
except json.JSONDecodeError as e:
# 如果解析失败,抛出异常
raise ValueError(f"Invalid JSON data: {e}")

@ -1,22 +0,0 @@
from datetime import datetime, timedelta
# 定义时间格式
date_format = "%Y-%m-%d"
# 获取当前日期,并按照定义的格式转换
current_date = datetime.now().strftime(date_format)
# 去除前导零
current_date = current_date.replace("-0", "-")
# 打印当前日期
print("当前日期:", current_date)
for day in range(1,16):
# 计算当前日期之前15天的日期
delta = timedelta(days=-day)
previous_date = (datetime.now() + delta).strftime(date_format)
# 去除前导零
previous_date = previous_date.replace("-0", "-")
print(previous_date)
# 打印之前15天的日期
print("之前15天的日期:", previous_date)

@ -1,58 +0,0 @@
# !/usr/bin/env python
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: tryselect.py
# @time: 2024/6/22 11:32
# @desc:
import mysql.connector
from mysql.connector import Error
import json
# 数据库配置信息
host = ''
database = 'nginxdb'
user = 'rtsw'
password = '123456'
# SQL查询语句
sql_query = "SELECT * FROM tasks" # 替换成你的表名和查询条件
# 连接到数据库
try:
connection = mysql.connector.connect(host=host,
database=database,
user=user,
password=password)
if connection.is_connected():
cursor = connection.cursor()
# 执行查询语句
cursor.execute(sql_query)
# 获取所有查询结果
rows = cursor.fetchall()
# 将查询结果转换为字典列表
# 假设你的表有列名为'id', 'name', 'age'等
columns = [i[0] for i in cursor.description] # 获取列名
data_list = [dict(zip(columns, row)) for row in rows] # 将每行数据转换为字典
# 将字典列表转换为JSON格式
json_data = json.dumps(data_list, ensure_ascii=False)
print(json_data) # 打印JSON格式的数据
print(data_list[0]["subject"])
except Error as e:
print("Error while connecting to MySQL", e)
finally:
# 关闭数据库连接
if connection.is_connected():
cursor.close()
connection.close()
print("MySQL connection is closed")

@ -1,21 +0,0 @@
CREATE TABLE `Servers` (
`server_name` VARCHAR(32) PRIMARY KEY,
`status VARCHAR(32) NOT NULL`,
`upstream` VARCHAR(32),
`detect_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`responseTime` varchar(255) NOT NULL COMMENT '响应时间',
`protocol` varchar(32) NOT NULL COMMENT '通信协议名称',
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '服务器列表';
CREATE TABLE `ServerHealthLog` (
`health_id` INT AUTO_INCREMENT PRIMARY KEY,
`server_name` VARCHAR(32),
`upstream` VARCHAR(32),
`detect_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`status` VARCHAR(32) NOT NULL,
`responseTime` varchar(255) NOT NULL COMMENT '响应时间',
`protocol` varchar(32) NOT NULL COMMENT '通信协议名称',
FOREIGN KEY (`server_name`) REFERENCES Servers(`server_name`),
INDEX `check_time_index` (`check_time`)
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '服务器历史信息记录表';

@ -1,11 +0,0 @@
CREATE TABLE IF NOT EXISTS `user` (
`username` varchar(255) NOT NULL,
`real_name` varchar(255) NOT NULL COMMENT '真名',
`ID` varchar(255) NOT NULL COMMENT '身份证号',
`password` varchar(255) NOT NULL COMMENT '密码',
`tel` varchar(255) NOT NULL COMMENT '电话号码',
PRIMARY KEY (`id`),
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '用户信息列表';

File diff suppressed because it is too large Load Diff

@ -1,187 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
<!-- 引入格式文件-->
<!-- <link rel="stylesheet" href="html&css.css"> -->
</head>
<body>
<style>
*{
margin: 0px;/*所有的外边距为0*/
padding: 0px;/*所有的内边距为0*/
box-sizing: border-box;/*规定两个并排的带边框的框*/
}
table{
text-align: center;
}
body{
background: url("./assets/images/button.jpg")no-repeat center;
padding-top: 25px;
}
.rg_layout{
width: 900px;
height: 500px;
border: 8px solid #EEEEEE;/*solid 定义实线*/
background-color: white;
margin: auto;
}
.rg_left{
float: none;
text-align: center;
margin: 15px;
}
.rg_left>p:first-child{
color: #FFD026;
font-size: 20px;
}
.rg_left>p:last-child{
color: #A6A6A6;
font-size: 20px;
}
.rg_center{
float: left;
}
.rg_right{
float: none;
margin: 250px;
padding-left: 10px;
white-space:nowrap;
}
.rg_right p{
font-size: 15px;
}
.rg_right p a{
color: coral;
}
.td_left{
padding-left: 250px;
width: 100px;
text-align: center;
height: 45px;
white-space:nowrap;
}
.td_right{
padding-left: 40px;
text-align: center;
white-space:nowrap;
}
.bt_center{
padding-left: 310px;
}
#username,#real_name,#ID,#password,#tel,#birthday,#checkcode{
width: 251px;
height: 32px;
border: 1px solid #A6A6A6;
/*设置边框圆角*/
border-radius: 5px;
padding-left: 10px;
}
#checkcode{
width: 110px;
}
#img_check{
height: 32px;
vertical-align: middle;/*设置图片的位置垂直居中*/
}
#btn_sub{
width: 100px;
height: 40px;
background-color: #FFD026;
border: 1px solid #FFD026;
padding-left: 10px;
}
</style>
<div class="rg_layout">
<div class="rg_left">
<p>新用户注册</p>
<p>USER REGISTER</p>
</div>
<div class="rg_center">
<div class="rg_form">
<form class="ant-form" action="#" method="post">
<table>
<tr><!--label 标签的作用是当点击文字也会跳到文本输出框-->
<!--for属性与ID属性对应规定 label 绑定到哪个表单元素。-->
<td class="td_left"><label for="username">用户名</label> </td>
<td class="td_right"><input type="text" name="username" id="username"> </td>
</tr>
<tr>
<td class="td_left"><label for="real_name">姓名</label> </td>
<td class="td_right"><input type="text" name="real_name" id="real_name"> </td>
</tr>
<tr><!--label 标签的作用是当点击文字也会跳到文本输出框-->
<td class="td_left"><label for="ID">身份证号</label> </td>
<td class="td_right"><input type="text" name="ID" id="ID"> </td>
</tr>
<tr>
<td class="td_left"><label for="password">密码</label> </td>
<td class="td_right"><input type="password" name="password" id="password"> </td>
</tr>
<tr>
<td class="td_left"><label for="tel">再次输入密码</label> </td>
<td class="td_right"><input type="password" name="tel" id="tel"> </td>
</tr>
<tr>
<td colspan="2" align="center" class="bt_center">
<input type="submit" value="注册" id="btn_sub">
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="rg_right">
<p><a href="LoginUI.html">返回登录界面</a></p>
</div>
</div>
</body>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取表单元素
var form = document.querySelector('.ant-form');
// 为表单添加提交事件监听器
form.addEventListener('submit', function(e) {
e.preventDefault(); // 阻止表单的默认提交行为
// 收集表单数据
var formData = {
//question_kind: document.getElementsByName('question_kind').value,
ID:document.getElementById('ID').value,
password: document.getElementById('password').value,
real_name:document.getElementById('real_name').value,
source:"frontend",
tel:document.getElementById('tel').value,
type:"register_message",
username: document.getElementById('username').value,
};
console.log(formData);
fetch('http://47.96.136.178:8080', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData) // 将表单数据转换为JSON字符串
})
.then(response => response.json()) // 转换响应为JSON
.then(data => {
console.log('Success:', data);
alert('反馈成功提交!');
})
.catch((error) => {
console.error('Error:', error);
alert('提交失败,请稍后重试!');
});
});
});
</script>
</html>

@ -1,131 +0,0 @@
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: Connector.py
# @time: 2024/6/19 9:20
# @desc:
import socket
import threading
import sys
from http.server import HTTPServer, BaseHTTPRequestHandler
from Server import *
# 全局变量
sockets = {}
socket_lock = threading.Lock()
exit_flag = False
# 维护连接的函数
def KeepConnection(sock, ip, port):
"""
@author: 原凯峰
@param sock:
@param ip:
@param port:
@return:
"""
while not exit_flag:
data = sock.recv(1024)
if not data:
print(f"Gateway disconnected from {ip}:{port}")
break
print(f"Received from gateway ({ip}:{port}): {data.decode()}")
with socket_lock:
del sockets[sock]
# 连接到网关的函数
def ConnectToGateway(ip, port):
"""
@author: 原凯峰
@param ip:
@param port:
@return:
"""
global exit_flag
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
with socket_lock:
sockets[sock] = (ip, port)
print(f"Connected to gateway at {ip}:{port}")
threading.Thread(target=KeepConnection, args=(sock, ip, port)).start()
def StartHttpServer():
"""
@author: 原凯峰
@return:
"""
global exit_flag
server_address = ('', 8080)
httpd = HTTPServer(server_address, CORSHTTPRequestHandler)
print(f'Starting httpd server on port 8080...')
try:
while not exit_flag:
httpd.handle_request() # 使用 handle_request 替代 serve_forever 以便可以检查 exit_flag
except KeyboardInterrupt:
pass
finally:
httpd.server_close()
print("HTTP server stopped")
# 发送消息到特定网关的函数
def SendMessageToGateway(ip, port, message):
"""
@author: 原凯峰
@param ip:
@param port:
@param message:
@return:
"""
with socket_lock:
# 查找特定的网关连接
for sock, (stored_ip, stored_port) in sockets.items():
if stored_ip == ip and stored_port == port:
try:
# 发送消息,这里假设消息是字符串格式
sock.sendall(message.encode('utf-8'))
print(f"Message sent to {ip}:{port}: {message}")
except socket.error as e:
print(f"Error sending message to {ip}:{port}: {e}")
return # 找到并发送消息后退出函数
# 如果没有找到连接
print(f"No connection found for {ip}:{port}")
# 示例发送消息到IP地址和端口
# 假设我们已经连接到了这个网关
def main():
global exit_flag
exit_flag = False # 初始化exit_flag
t = threading.Thread(target=StartHttpServer)
t.start()
while not exit_flag:
command = input("Enter command (/connect_gateway/exit): ")
# if command == "start_http_server":
# t = threading.Thread(target=StartHttpServer)
# t.start()
if command == "connect_gateway":
ip = input("Enter the gateway IP address: ")
port = int(input("Enter the gateway port: "))
ConnectToGateway(ip, port)
elif command == "exit":
exit_flag = True
print("Exiting program...")
break
else:
print("Unknown command")
# StartHttpServer函数修改
if __name__ == "__main__":
main()

@ -1,167 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: KernelToController.py
# @time: 2024/7/2 15:16
# @desc:
import requests
import socket
import json
import time
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def __init__(self, *args, **kwargs):
super(CustomEncoder, self).__init__(*args, **kwargs)
self.prefix = {'number': '1', 'source': 'backend', 'kind': 'server_health_list'}
def encode(self, obj):
if not isinstance(obj, dict):
raise TypeError("Object must be a dict.")
# 将prefix添加到原始字典的前面
encoded_dict = {**self.prefix, **obj}
return super(CustomEncoder, self).encode(encoded_dict)
def calResponseTime(time_str1, time_str2, time_format):
# 将字符串时间转换为datetime对象
time1 = datetime.strptime(time_str1, time_format)
time2 = datetime.strptime(time_str2, time_format)
time_difference = time2 - time1
seconds_difference = time_difference.total_seconds()
return seconds_difference
# 定义时间格式
time_format = "%a, %d %b %Y %H:%M:%S GMT"
# 目标URL
url = 'http://127.0.0.1/status?format=json'
# 发送数据的IP地址和端口
target_ip = '47.96.136.178'
target_port = 8080
# 定义一个数组来存储last_check_time的值
last_check_times = []
last_receive_times = []
last_response_times = []
tmp = ''
pos = 0
while True:
# 从URL获取数据
response = requests.get(url)
data = response.json()
tip = 0
pos = pos + 1
# 检查 'servers' 和 'server' 键是否存在
if 'servers' in data and 'server' in data['servers']:
# 遍历服务器数据
for server in data['servers']['server']:
# 将对应的值添加到数组中
if (pos == 1):
# 数组初添加
last_check_times.append(server['last_check_time'])
else:
# 修正处理json数据
server['last_check_time'] = tmp
# 存放到数组中
last_check_times[tip] = tmp
# 修正调整
if (server['last_receive_time'] == ''):
server['last_receive_time'] = 'Null'
if (pos == 1):
last_receive_times.append(server['last_receive_time'])
else:
last_receive_times[tip] = server['last_receive_time']
tip = tip + 1
print("last_check_times:", last_check_times)
print("last_receive_times:", last_receive_times)
##分析计算出服务器响应时间:
for i in range(len(last_check_times)):
# 初次添加
if (pos == 1):
if (last_receive_times[i] == 'Null'):
last_response_times.append('Null')
if (last_receive_times[i] != 'Null'):
responseTime = calResponseTime(last_check_times[i], last_receive_times[i], time_format)
last_response_times.append(responseTime)
else:
if (last_receive_times[i] == 'Null'):
last_response_times[i] = 'Null'
if (last_receive_times[i] != 'Null'):
responseTime = calResponseTime(last_check_times[i], last_receive_times[i], time_format)
last_response_times[i] = responseTime
# 加入到发送数据中:
for server, responseTime in zip(data['servers']['server'], last_response_times):
server['last_response_time'] = responseTime
for i in range(len(last_check_times)):
if (last_receive_times[i] != 'Null'):
tmp = last_receive_times[i]
last_check_times[i] = last_receive_times[i]
# 打印数组内容,查看存储的值
print("last_response_times:", last_response_times)
# 使用自定义的编码器将数据转换为JSON格式的字符串
json_data = json.dumps(data, cls=CustomEncoder)
print(json_data)
# 目标服务器的IP地址和端口
target_url = 'http://47.96.136.178:8080'
# 发送POST请求
# 指定发送的内容类型为JSON
headers = {'Content-Type': 'application/json'}
response = requests.post(target_url, data=json_data, headers=headers)
# 检查请求是否成功
if response.status_code == 200:
print("数据成功发送。")
else:
print("数据发送失败,状态码:", response.status_code)
print("数据已发送到IP{},端口:{}".format(target_ip, target_port))
# 等待2.5秒
time.sleep(2.5)
# 读取文件
def read_log(file_path):
with open(file_path, 'r') as file:
# 读取所有行
log_lines = [line.strip() for line in file]
return log_lines
# # 指定文件路径
# file_path = '/usr/local/nginx/logs/access.log'
#
# # 指定目标IP和端口
# targeturl = 'http://47.96.136.178:8080'
# 构造JSON数据并发送
# def send_json(url, data):
# headers = {'Content-Type': 'application/json'}
# # 将数据构造为JSON格式
# json_data = json.dumps({"logs": data})
# response = requests.post(url, data=json_data, headers=headers)
# return response
# try:
# # 读取日志文件并转换为JSON
# log_data = read_log(file_path)
#
# # 发送数据
# response = send_json(targeturl, log_data)
#
# # 打印响应状态码和内容
# print(f'Status Code: {response.status_code}')
# print(f'Response Content: {response.text}')
# except Exception as e:
# print(f'An error occurred: {e}')

@ -1,53 +0,0 @@
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: Server.py
# @time: 2024/6/19 9:22
# @desc:
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from MessageHandler.PreDataProcessor import *
import time
class CORSHTTPRequestHandler(BaseHTTPRequestHandler):
def do_OPTIONS(self):
self.send_response(204)
self.send_header('Content-type', 'text/plain')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
self.end_headers()
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
print("Request line:", self.requestline)
print("Headers:", self.headers)
print("Body:", post_data.decode('utf-8'))
# 处理程序
MessageProcessor = preDataProcessor(post_data)
# response = {"POST": "request received"}
# self.wfile.write(str(response).encode('utf-8'))
# time.sleep(1)
backMessage =MessageProcessor.returnMessage
response = {"POST": backMessage}
self.wfile.write(str(json.dumps(response)).encode('utf-8'))
# self.wfile.write("{\"POST\": \"request received\"}".encode('utf-8'))
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
self.wfile.write(b"Hello, world!")

@ -1,60 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
# @author: 原凯峰
# @contact: 2894340009@qq.com
# @software: pycharm
# @file: aiohttpserver.py
# @time: 2024/6/19 23:11
# @desc:
import asyncio
import aiohttp
from aiohttp import web
async def process_data(data):
# 这里模拟异步数据处理,例如通过网络请求或数据库操作
await asyncio.sleep(1) # 模拟异步操作的延时
return f"Processed: {data}"
# 定义CORS中间件
async def add_cors_headers(request, handler):
# 设置CORS相关的响应头
response = handler(request) # 先调用handler处理请求获取response
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
# 检查请求方法是否为OPTIONS
if request.method == 'OPTIONS':
# OPTIONS请求返回204状态码不返回body
return web.Response(status=204, headers=response.headers)
return response
# 创建应用
app = web.Application(middlewares=[add_cors_headers])
# 定义路由和视图函数
async def handle_options(request):
return web.Response(status=204)
async def handle_post(request):
data = await request.post()
post_data = await data.text() # 异步读取POST数据
processed_data = await process_data(post_data)
return web.json_response({
"POST": "request received",
"processed_data": processed_data
})
async def process_data(data):
await asyncio.sleep(1) # 模拟异步操作的延时
return f"Processed: {data}"
# 添加路由
app.add_routes([web.route('OPTIONS', '/', handle_options),
web.route('POST', '/', handle_post)])
if __name__ == '__main__':
web.run_app(app, host='127.0.0.1', port=8080)

@ -1,23 +0,0 @@
def query_ip_location(ip_address, ip_data_file):
result = None
with open(ip_data_file, 'r', encoding='utf-8') as f:
for line in f:
if line.strip(): # 确保行非空
parts = line.split()
if len(parts) >= 3:
start_ip = parts[0]
end_ip = parts[1]
location_info = ' '.join(parts[2:])
if ip_address >= start_ip and ip_address <= end_ip:
result = location_info.split('')[1].strip() # 获取中国的地区信息
break
return result
# 示例用法
ip_data_file = 'china_ip_address.txt'
ip_address_to_query = '1.173.45.67' # 替换为你想要查询的IP地址
location = query_ip_location(ip_address_to_query, ip_data_file)
if location:
print(f"{ip_address_to_query} 所在的省级地域是:{location}")
else:
print(f"未找到 {ip_address_to_query} 的地理位置信息。")

@ -1,363 +0,0 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.css" rel="stylesheet" type="text/css" />
<script>
var data=[
{
message:'192.172.0.1 is Master,192.173.0.2 is Backup'
}
];
  renderEl(data.message);
paintVis(data.message);
function renderEl(arr) {
        let str = '';
        str += `
           <table>
<caption>
当前网络中网关情况:
</caption>
<thead>
<tr>
<th scope="col">服务器IP</th>
<th scope="col">服务器状态</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">${arr.substr(0,arr.indexOf("Master")-3)}</th>
<td>Master</td>
</tr>
<tr>
<th scope="row">${arr.substr(arr.indexOf("Master")+6,arr.indexOf("Backup")-3)}</th>
<td>Backup</td>
</tr>
</table>
`;
const el = document.getElementById('wrap');
        el.innerHTML = str;
}
function paintVis(arr){
var nodes = new vis.DataSet([
{ id: 1, label: 'keepalived:vrrp\n 192.168.229.130',color: {background: 'lightgreen'}},
{ id: 2, label: arr.substring(0,arr.indexOf("Master")-3),color: {background: 'lightgreen'}},
{ id: 3, label: arr.substring(arr.indexOf("Master")+6,arr.indexOf("Backup")-3),color: {background: 'grey'}},
{ id: 4, label: 'web Server\n 192.168.229.129.81',color: {background: 'lightgreen'}},
{ id: 5, label: 'web Server\n 192.168.229.129.81',color: {background: 'grey'}},
{ id: 6, label: '客户端',color: {background: 'lightgreen'} },
]);
var edges = new vis.DataSet([
{ from: 6, to: 1 , color: {color:'#00ff00'}},
{ from: 1, to: 2 , color: {color:'#00ff00'}},
{ from: 1, to: 3 , color: {color:'grey'}},
{ from: 2, to: 4 , color: {color:'#00ff00'}},
{ from: 2, to: 5 , color: {color:'#00ff00'}},
{ from: 3, to: 4 , color: {color:'grey'}},
{ from: 3, to: 5 , color: {color:'#00ff00'}},
]);
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
nodes: {
shape:'dot',
font: {
color: '#000', // 字体的颜色
size: 10 // 显示字体大小
},
scaling: {
min: 20,
max: 40 // 缩放效果比例
},
borderWidth: 1,
color: {
border: 'white',
// 若是引用图标,背景颜色
}
},
groups: {
ws: { // 系统定义的形状 dot等 这些官网都可以找到
shape: 'square',
color: 'white'
}
},
layout: {
randomSeed: 1 // 配置每次生成的节点位置都一样参数为数字1、2等
},
physics: {
// barnesHut: { gravitationalConstant: -30000 },
barnesHut: {
gravitationalConstant: 0,
springConstant: 0,
springLength: 0
},
stabilization: true
// { iterations: 2500 }
},
interaction: {
// navigationButtons: true,
hover: false, // 鼠标移过后加粗该节点和连接线
selectConnectedEdges: false, // 选择节点后是否显示连接线
hoverConnectedEdges: false, // 鼠标滑动节点后是否显示连接线
tooltipDelay: 200,
zoomView: false // 是否能缩放画布
},
edges: {
label:'Solid',
smooth: {type: "discrete"},
color: { // 连接线的样式
hover: '#848484',
inherit: 'from',
opacity: 1.0
},
shadow: true, // 连接线阴影配置
smooth: true // 是否显示方向箭头
// arrows: {to : true }//箭头指向from节点
}
};
var network = new vis.Network(container, data, options);
}
</script>
<style>
table{
width: 50%;
border-collapse: collapse;
margin: auto;
}
table caption{
font-size: large;
font-weight: bold;
margin: 1em 0;
}
th,td{
border: 1px solid #999;
text-align: center;
padding: 20px 0;
}
table thead tr{
background-color: #008c8c;
color: #fff;
}
table tbody tr:nth-child(odd){
background-color: #eee;
}
table tbody tr:hover{
background-color: #ccc;
}
table tbody tr td:first-child{
color: #f40;
}
table tfoot tr td{
text-align: right;
padding-right: 20px;
}
#dropdownMenu {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-item {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-item:hover {
background-color: #f1f1f1;
}
</style>
<header>
<div style="text-align: center; padding-right: 10px; flex: 1 1 0%;font-size: large;background-color: rgb(227, 234, 234);">主备切换</div>
</header>
<body>
<table>
<caption>
当前网络中网关情况:
</caption>
<div id="wrap"></div>
</body>
<div id="dropdownMenu" class="dropdown-content">
<a href="#" class="dropdown-item" id="toggleOpen">开启</a>
<a href="#" class="dropdown-item" id="toggleClose">关闭</a>
</div>
<h1>网络拓扑图<button id="submitBtn">提交</button></h1>
<div id="doubleClickArea">
<div id="mynetwork" style="width:auto; height:500px; border:1px solid lightgray;"></div>
</div>
<script>
var nodes = new vis.DataSet([
{ id: 1, label: 'keepalived:vrrp\n 192.168.229.130',color:'lightgreen'},
{ id: 2, label: 'nginx负载均衡\n 192.168.229.128:80',color:'lightgreen'},
{ id: 3, label: 'nginx负载均衡\n 192.168.229.129.80',color: 'grey'},
{ id: 4, label: 'web Server\n 192.168.229.129.81',color:'lightgreen'},
{ id: 5, label: 'web Server\n 192.168.229.129.81',color: 'grey'},
{ id: 6, label: '客户端',color:'lightgreen' },
]);
var edges = new vis.DataSet([
{ id: 7,from: 6, to: 1 , color: '#00ff00'},
{ id: 8,from: 1, to: 2 , color: '#00ff00'},
{ id: 9,from: 1, to: 3 , color: 'grey'},
{ id: 10,from: 2, to: 4 , color: '#00ff00'},
{ id: 11,from: 2, to: 5 , color: '#00ff00'},
{ id: 12,from: 3, to: 4 , color: 'grey'},
{ id: 13,from: 3, to: 5 , color: '#00ff00'},
]);
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
nodes: {
shape:'dot',
font: {
color: '#000', // 字体的颜色
size: 10 // 显示字体大小
},
scaling: {
min: 20,
max: 40 // 缩放效果比例
},
borderWidth: 1,
color: {
border: 'white',
// 若是引用图标,背景颜色
}
},
groups: {
ws: { // 系统定义的形状 dot等 这些官网都可以找到
shape: 'square',
color: 'white'
}
},
layout: {
randomSeed: 1 // 配置每次生成的节点位置都一样参数为数字1、2等
},
physics: {
// barnesHut: { gravitationalConstant: -30000 },
barnesHut: {
gravitationalConstant: 0,
springConstant: 0,
springLength: 0
},
stabilization: true
// { iterations: 2500 }
},
interaction: {
// navigationButtons: true,
hover: true, // 鼠标移过后加粗该节点和连接线
selectConnectedEdges: false, // 选择节点后是否显示连接线
hoverConnectedEdges: false, // 鼠标滑动节点后是否显示连接线
tooltipDelay: 200,
zoomView: false // 是否能缩放画布
},
edges: {
label:'Solid',
smooth: {type: "discrete"},
color: { // 连接线的样式
inherit: 'from',
},
shadow: false, // 连接线阴影配置
smooth: true // 是否显示方向箭头
// arrows: {to : true }//箭头指向from节点
}
};
var network = new vis.Network(container, data, options);
network.on('click', function (event) {
nodeId = event.nodes[0]; // 获取被点击的节点ID
nodeData = nodes.get(nodeId); // 根据节点ID获取节点数据
if (nodeData) {
console.log('Clicked on node: ' + nodeData.id + '\n' +
'Entity Info: ' + nodeData.label+ '\n' +
'Color Info:' + nodeData.color);
// 可以在这里添加更多的逻辑来处理点击事件
}
});
var doubleClickArea = document.getElementById('doubleClickArea');
var dropdownMenu = document.getElementById('dropdownMenu');
// 为双击区域添加双击事件监听器
doubleClickArea.addEventListener('dblclick', function(event) {
// 显示下拉菜单
var nodeToUpdate = nodes.get(nodeId);
if (nodeToUpdate.color === 'grey') {
nodeToUpdate.color = '#00ff00';
} else {
nodeToUpdate.color = 'grey';
}
nodes.update([nodeToUpdate]);
});
function updateEdgeColor() {
// 获取所有节点的颜色
for(var i=1;i<=6;i++){
for(var j=1;j<=6;j++)
{
var node1Color =nodes.get(i).color;
var node2Color =nodes.get(j).color;
var edgeColor = ((node1Color =="lightgreen") && (node2Color =="lightgreen")) ? 'green' : 'grey';
var edge = edges.get({ from: i, to: j });
if (edge) {
edge.color = { color: edgeColor };
console.log("Update")
edges.update(edge);
}
}
}
// 更新边的颜色
for(var i=0;i<=6;i++)
{
for(var j=0;j<=6;j++)
{
var edge = edges.get({ from: i, to: j });
if (edge) {
edge.color = { color: edgeColor };
console.log("Update")
edges.update(edge);
}
}
}
}
setInterval(updateEdgeColor, 3000); // 每3000毫秒3秒更新一次
var submitButton = document.getElementById('submitBtn');
// 为提交按钮添加点击事件监听器
submitButton.addEventListener('click', function() {
// 从Vis.js网络图中获取当前的nodes信息
var currentNodes = nodes.get();
// 将nodes信息转换为JSON格式
var nodesJson = JSON.stringify(currentNodes);
// 使用fetch API发送数据到后端服务器
fetch('YOUR_BACKEND_ENDPOINT', { // 替换为你的后端服务器端点
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: nodesJson
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
});
</script>

@ -7,8 +7,6 @@
<link rel="stylesheet" type="text/css" href="msgList.css"> <link rel="stylesheet" type="text/css" href="msgList.css">
<link rel="stylesheet" href="./assets/css/style.css"> <link rel="stylesheet" href="./assets/css/style.css">
<script type="text/javascript" src="./assets/js/jquery.js"></script> <script type="text/javascript" src="./assets/js/jquery.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="./echarts.min.js"></script>
</head> </head>
<style> <style>
#pie { #pie {
@ -25,9 +23,6 @@
background-color: #dce0e9; background-color: #dce0e9;
position: fixed; position: fixed;
} }
.wrap-hidden{
transform: translateX(-150%);
}
.header{ .header{
width: 100%; width: 100%;
height: 65px; height: 65px;
@ -236,7 +231,7 @@ min-height: 520px;
overflow: hidden; overflow: hidden;
} }
.lie { .lie {
width: 12%; width: 23%;
display: inline-block; display: inline-block;
font: 13px sans-serif; font: 13px sans-serif;
} }
@ -258,11 +253,12 @@ min-height: 520px;
overflow: hidden; overflow: hidden;
} }
.lia { .lia {
width: 12%; width: 23%;
display: inline-block; display: inline-block;
font: 13px sans-serif; font: 13px sans-serif;
} }
.lia a { .lia a {
display: block;
font-size: larger; font-size: larger;
color: rgb(0, 0, 0); color: rgb(0, 0, 0);
text-align: center; text-align: center;
@ -281,54 +277,11 @@ min-height: 520px;
background: #06b81a; background: #06b81a;
} }
.modal {
display: none;
position: fixed;
z-index: 999;
left: 0; }
top: 0;
width: 100px;
height: 100px;
overflow: auto;
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 50%;
max-width: 600px; /* 限制图表的最大宽度 */
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
}
#chart-container {
width: 500px;
height: 800px;
margin: auto;
}
.circle-tag {
width: 20px;
height: 20px;
border-radius: 100%;
background-color: #3498db;
color: white;
text-align:left;
font-size: 16px;
font-family: Arial, sans-serif;
display: grid;
}
</style> </style>
<header class="top-navigation"> <header class="top-navigation">
<div class="container"> <div class="container">
@ -337,7 +290,6 @@ min-height: 520px;
</div> </div>
</header> </header>
<body> <body>
<button id="toggleSidebar">隐藏/显示 侧边栏</button>
<div class="wrap"> <div class="wrap">
<div class="header">消息过滤器</div> <div class="header">消息过滤器</div>
<div class="nav"> <div class="nav">
@ -414,7 +366,24 @@ min-height: 520px;
<h4 class="h3">消息类别统计表</h4> <h4 class="h3">消息类别统计表</h4>
<table class="card-table"> <table class="card-table">
<tbody class="table-body flex-center"> <tbody class="table-body flex-center">
<div id="graph"></div> <tr class="table-row flex-center">
<th class="table-heading" scope="col">北京</th>
<td class="table-data">
<div class="chart-bar" data-chart-bar="beijing"></div>
</td>
</tr>
<tr class="table-row flex-center">
<th class="table-heading" scope="col">上海</th>
<td class="table-data">
<div class="chart-bar" data-chart-bar="shanghai"></div>
</td>
</tr>
<tr class="table-row flex-center">
<th class="table-heading" scope="col">长沙</th>
<td class="table-data">
<div class="chart-bar" data-chart-bar="长沙"></div>
</td>
</tr>
</tbody> </tbody>
</table> </table>
<span class="tooltip text" data-tooltip></span> <span class="tooltip text" data-tooltip></span>
@ -430,257 +399,108 @@ min-height: 520px;
</div> </div>
</div> </div>
</div> </div>
<script src="./assets/js/script.js" type="module" defer></script>
<div class="piechart" id="pie"></div> <div class="piechart" id="pie"></div>
<script> <script>
var pie = echarts.init(document.getElementById('pie'));
pieOption = {
title: {
text: '数据统计饼状图'
},
tooltip: {
show: true,
trigger: "item",
backgroundColor: "#1677FF",
// {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
formatter: "{a}{b}<br/>{c}吨({d}%)"
},
color: ['#3e87ff', '#65b2f3', '#b9cfec'],
series: [
{
name: '品种',
type: 'pie',
// 数组的第一项是内半径,第二项是外半径;可以设置不同的内外半径显示成圆环图
radius: '50%',
// 饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标;设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度
center: ['50%', '50%'],
data: [
{ value: 2000, name: '北京' },
{ value: 2000, name: '上海' },
{ value: 2000, name: '长沙' },
</script> ],
<!-- 假设这是您的消息列表容器 --> itemStyle: {
<div id="my_msg_list"> // 显示图例
<div class="my_msg_list_view"> normal: {
<div class="my_msg_list_box"> label: {
<div class="my_msg_list_con"> show: true
<div class="my_msg_list_title"> },
<span >消息列表:</span> labelLine: {
<a class="fr">清空所有消息</a> show: true
<span class="line fr"></span> }
<a class="fr">全部标记为已读</a>
</div>
<div class="ule">
<div class="lie"><a href="#home">服务器列表</a></div>
<div class="lie"><a href="#location">地区</a></div>
<div class="lie"><a href="#news">距离上次响应时间</a></div>
<div class="lie"><a href="#contact">当前服务器状态</a></div>
<div class="lie"><a href="#about">返回消息报头</a></div>
</div>
<div id="mylist"></div>
<!-- 消息列表将在这里动态生成 -->
<div class="page-box">
</div>
</div>
</div>
</div>
</div>
</div>
</html>
<script>
// 假设这是您接收到的JSON数据
var jsonData = [
{
"server": "127.0.0.1",
"location":"北京",
"responseTime": "100ms",
"status": "正常",
"protocol": "TCP",
"date": "2024-07-01",
"value":200
},
{
"server": "127.0.0.2",
"location":"上海",
"responseTime": "1300ms",
"status": "受损",
"protocol": "TCP",
"date": "2024-07-01",
"value":30
},
{
"server": "127.0.0.3",
"location":"广州",
"responseTime": "70ms",
"status": "繁忙",
"protocol": "TCP",
"date": "2024-07-01",
"value":50
}
];
var jsonData2 = [
{
"server": "127.0.0.1",
"location":"北京",
"responseTime": "70ms",
"status": "正常",
"protocol": "TCP",
"date": "2024-07-01",
"value":250
},
{
"server": "127.0.0.2",
"location":"上海",
"responseTime": "150ms",
"status": "正常",
"protocol": "TCP",
"date": "2024-07-01",
"value":70
},
{
"server": "127.0.0.3",
"location":"广州",
"responseTime": "70ms",
"status": "繁忙",
"protocol": "TCP",
"date": "2024-07-01",
"value":50
}
];
var jsonData3 = [
{
"server": "127.0.0.1",
"location":"北京",
"responseTime": "75ms",
"status": "正常",
"protocol": "TCP",
"date": "2024-07-01",
"value":300
},
{
"server": "127.0.0.2",
"location":"上海",
"responseTime": "120ms",
"status": "正常",
"protocol": "TCP",
"date": "2024-07-01",
"value":100
},
{
"server": "127.0.0.3",
"location":"广州",
"responseTime": "100ms",
"status": "正常",
"protocol": "TCP",
"date": "2024-07-01",
"value":60
}
];
// 函数用于更新消息列表
function updateMessageList(data) {
var msgListContainer = document.getElementById('mylist');
msgListContainer.innerHTML = ''; // 清空现有内容
data.forEach(function(item) {
var msgItem = document.createElement('div');
msgItem.className = 'msg_item';
msgItem.innerHTML = `
<li class="msg_list_ul_li">
<div class="ula">
<div class="lia"><a href="test.html"><div class="circle-tag"></div><span></span>${item.server}</a></div>
<div class="lia"><a href="#location">${item.location}</a></div>
<div class="lia"><a href="#news">${item.responseTime}</a></div>
<div class="lia"><a href="#contact">${item.status}</a></div>
<div class="lia"><a href="#about">${item.protocol}</a></div>
</div>
<em class="data-time" style="float: right;padding-right:10px">${item.date}</em>
</li>
`;
msgListContainer.appendChild(msgItem);
});
}
function updateGraph(data) {
var msgListContainer = document.getElementById('graph');
msgListContainer.innerHTML = ''; // 清空现有内容
data.forEach(function(item) {
var msgItem = document.createElement('div');
msgItem.className = 'msg_item';
msgItem.innerHTML = `
<tr class="table-row flex-center">
<th class="table-heading" scope="col">${item.server}</th>
<td class="table-data">
<div class="chart-bar" data-chart-bar="&{item.server}">${item.value}</div>
</td>
</tr>
`;
msgListContainer.appendChild(msgItem);
});
}
var pie = echarts.init(document.getElementById('pie'));
// 饼状图配置项
var pieOption = {
title: {
text: '数据统计饼状图'
},
tooltip: {
show: true,
trigger: "item",
backgroundColor: "#1677FF",
formatter: "{a}{b}<br/>{c}次({d}%)"
},
color: ['#3e87ff', '#65b2f3', '#b9cfec'],
series: [
{
name: '服务器名',
type: 'pie',
radius: '50%',
center: ['50%', '50%'],
// 初始化为空数组数据将根据jsonData动态设置
data: [],
itemStyle: {
normal: {
label: {
show: true
}, },
labelLine: { emphasis: {
show: true // 图形阴影的模糊大小
shadowBlur: 10,
// 阴影水平方向上的偏移距离
shadowOffsetX: 0,
// 阴影颜色
shadowColor: 'rgba(0, 0, 0, 0.5)'
} }
},
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
} }
} }
} ]
] };
};
// 将jsonData转换为饼状图的数据格式
function generatePieData(jsonData) {
return jsonData.map(function (item) {
return {
value: item.value,
name: item.server
};
});
}
function updatePieChart(jsonData) {
pieOption.series[0].data = generatePieData(jsonData);
pie.setOption(pieOption); pie.setOption(pieOption);
} </script>
//侧边栏隐藏显示切换 <div class="my_msg_list">
document.addEventListener('DOMContentLoaded', function () { <div class="my_msg_list_view">
var toggleSidebarButton = document.getElementById('toggleSidebar'); <div class="my_msg_list_box">
var sidebar = document.querySelector('.wrap'); <div class="my_msg_list_con">
<div class="my_msg_list_title">
toggleSidebarButton.addEventListener('click', function () { <span >消息列表:</span>
sidebar.classList.toggle('wrap-hidden'); <a class="fr">清空所有消息</a>
}); <span class="line fr"></span>
}); <a class="fr">全部标记为已读</a>
</div>
function updateAll(){ <div class="ule">
updatePieChart(jsonData);// 调用函数以更新消息列表 <div class="lie"><a href="#home">服务器列表</a></div>
updateGraph(jsonData) <div class="lie"><a href="#news">距离上次响应时间</a></div>
updateMessageList(jsonData); <div class="lie"><a href="#contact">当前服务器状态</a></div>
setTimeout(function(){ <div class="lie"><a href="#about">返回消息报头</a></div>
updateAll2(); </div>
},5000); <div class="ula">
} <div class="lia"><a href="#home"><span><div class="square"></div></span>北京</a></div>
function updateAll2(){ <div class="lia"><a href="#news">100ms</a></div>
updatePieChart(jsonData2);// 调用函数以更新消息列表 <div class="lia"><a href="#contact">正常</a></div>
updateGraph(jsonData2) <div class="lia"><a href="#about">TCP</a></div>
updateMessageList(jsonData2); </div>
setTimeout(function(){ <em class="data-time" style="float: right;padding-right:10px">2019-03-28</em>
updateAll3(); <li class="msg_list_ul_li">
},5000) <div class="ula">
} <div class="lia"><a href="#home">长沙</a></div>
function updateAll3(){ <div class="lia"><a href="#news">1300ms</a></div>
updatePieChart(jsonData3);// 调用函数以更新消息列表 <div class="lia"><a href="#contact">受损</a></div>
updateGraph(jsonData3) <div class="lia"><a href="#about">TCP</a></div>
updateMessageList(jsonData3); </div>
} <em class="data-time" style="float: right;padding-right:10px">2019-03-28</em>
updateAll(); </li>
</script> <li class="msg_list_ul_li">
</body> <div class="ula">
<div class="lia"><a href="#home">上海</a></div>
<div class="lia"><a href="#news">70ms</a></div>
<div class="lia"><a href="#contact">繁忙</a></div>
<div class="lia"><a href="#about">TCP</a></div>
</div>
<em class="data-time" style="float: right;padding-right:10px">2019-03-28</em>
</li>
</ul>
</div>
<div class="page-box">
</div>
</div>
</div>
</div>
</div>
</div>
</html> </html>

@ -170,12 +170,9 @@
<!-- banner的平铺部分 --> <!-- banner的平铺部分 -->
<div id="banner"> <div id="banner">
<div class="banner_con"> <div class="banner_con">
<a href="./index.html">
<img src="./assets/images/R-C.png" <img src="./assets/images/R-C.png"
height="466px" height="466px"
width="1000px" width="1000px">
>
</a>
</div> </div>
</div> </div>
<!-- 新闻列表的版心部分 --> <!-- 新闻列表的版心部分 -->

@ -1,41 +0,0 @@
<div class="sidebar">
<div class="menu-item">北京</div>
<div class="menu-item">长沙</div>
<div class="menu-item">上海</div>
<!-- 更多菜单项... -->
</div>
<button id="toggleIndent">切换缩进</button>
<style>
/* 初始的侧边栏样式 */
.sidebar {
width: 200px; /* 侧边栏宽度 */
background-color: #f4f4f4; /* 侧边栏背景颜色 */
padding: 10px; /* 侧边栏内边距 */
}
/* 菜单项样式 */
.menu-item {
padding: 8px 20px; /* 菜单项内边距 */
margin-bottom: 5px; /* 菜单项之间的间隔 */
background-color: #ddd; /* 菜单项背景颜色 */
cursor: pointer; /* 鼠标悬停时显示为指针 */
transition: background-color 0.3s; /* 背景颜色变化的过渡效果 */
}
/* 缩进效果的样式 */
.indented {
margin-left: 20px; /* 缩进的距离 */
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
var toggleIndentButton = document.getElementById('toggleIndent');
var menuItems = document.querySelectorAll('.menu-item');
toggleIndentButton.addEventListener('click', function () {
menuItems.forEach(function (item) {
item.classList.toggle('indented');
});
});
});
</script>

@ -221,8 +221,7 @@ body {
.chart-card .chart-bar { .chart-card .chart-bar {
background-color: var(--medium-slate-blue); background-color: var(--medium-slate-blue);
height: 50%; height: 100%;
width: 100%;
transform-origin: bottom; transform-origin: bottom;
transition: transform var(--transition-2); transition: transform var(--transition-2);
} }

File diff suppressed because one or more lines are too long

@ -1,363 +0,0 @@
@charset "UTF-8";
/* CSS Document */
.bg{
margin:0 auto;
width:100%;
min-height:100vh;
background:url(../images/bg2.jpg) no-repeat;
background-size: cover;
padding-top:0rem;
padding:0rem 0.2rem;
}
/*.conIn{
display:flex;
display: -webkit-flex;}*/
.title{
width:100%;
font-size:0.12rem;
line-height:0.3rem;
color:rgba(14,253,255,1);
text-align:center;
font-weight:bold;
}
.border_bg_leftTop{
position:absolute;
left:-0.008rem;
top:-0.04rem;
width:0.37rem;
height:0.05rem;
display:block;
background: url(../images/title_left_bg.png) no-repeat;
background-size:cover;}
.border_bg_rightTop{
position:absolute;
right:-0.01rem;
top:-0.01rem;
width:0.1rem;
height:0.1rem;
display:block;
background:url(../images/border_bg.jpg) no-repeat;
background-size:cover;}
.border_bg_leftBottom{
position:absolute;
left:-0.008rem;
bottom:-0.008rem;
width:0.1rem;
height:0.1rem;
display:block;
background:url(../images/border_bg.jpg) no-repeat;
background-size:cover;}
.border_bg_rightBottom{
position:absolute;
right:-0.01rem;
bottom:-0.01rem;
width:0.08rem;
height:0.08rem;
display:block;
background:url(../images/title_right_bg.png) no-repeat;
background-size:cover;}
.leftMain{
width:75%;
float:left;
padding-right:0.1rem;
padding-top:0.1rem;
}
.rightMain{
width:25%;
float:left;
padding-top:0.1rem;}
.leftMain_top{
width:100%;
padding-bottom:0.1rem;}
.leftMain_top ul{
display:flex;
display: -webkit-flex;
}
.leftMain_top ul li{
float:left;
width:25%;
padding-right:0.1rem;}
.leftMain_top ul li:last-child{
padding:0;}
.leftMain_top ul li .liIn{
border:0.008rem solid rgba(14,253,255,0.5);
width:100%;
min-height:60px;
position:relative;
padding:0.08rem 0.05rem;
}
.leftMain_top ul li .liIn h3{
font-size:0.08rem;
color:#fff;
margin-bottom:0.05rem;
}
.leftMain_top ul li .liIn .shu{
font-size:0.12rem;
color:rgba(14,253,255,1);
font-family:dig;
margin-bottom:0.02rem;}
.leftMain_top ul li .liIn .shu i{
font-size:0.04rem;
margin-left:0.06rem;
font-style:normal;}
.leftMain_top ul li .liIn .zi{
font-size:0.04rem;
color:#fff;
position:relative;
z-index:10;}
.leftMain_top ul li .liIn .zi .span1{
margin-right:0.1rem;}
.leftMain_middle{
width:100%;
padding-bottom:0.1rem;
display:flex;
display: -webkit-flex;}
.leftMain_middle .leftMain_middle_left{
width:60%;
padding-right:0.1rem;}
.leftMain_middle .leftMain_middle_left .leftMain_middle_leftIn{
border:0.008rem solid rgba(14,253,255,0.5);
width:100%;
min-height:60px;
position:relative;
padding:0.08rem 0.05rem;
}
.leftMain_middle .leftMain_middle_left .leftMain_middle_leftIn h3{
font-size:0.08rem;
color:#fff;
margin-bottom:0.05rem;
}
.leftMain_middle .leftMain_middle_left .leftMain_middle_leftIn .biaoge{
min-height:200px;}
.leftMain_middle .leftMain_middle_right{
width:40%;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn{
border:0.008rem solid rgba(14,253,255,0.5);
width:100%;
min-height:60px;
position:relative;
padding:0.08rem 0.05rem;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn h3{
font-size:0.08rem;
color:#fff;
margin-bottom:0.05rem;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge{
min-height:200px;}
/*左边中间部分排行榜*/
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai{
width:100%;
overflow:hidden;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn{
display:flex;
display: -webkit-flex;
align-items:center;
color:#fff;
font-size:0.06rem;
height:0.18rem;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_left{
width:25%;
position:relative;
padding-left:0.14rem;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_left .bot{
width:0.08rem;
height:0.08rem;
background:#f78cf3;
border-radius:1000px;
display:block;
position:absolute;
left:0.02rem;
top:0;
bottom:0;
margin:auto 0;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn2 .liIn_left .bot{
background:#e7feb8;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn3 .liIn_left .bot{
background:#fdea8a;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn4 .liIn_left .bot{
background:#8ff9f8;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn5 .liIn_left .bot{
background:#d890fa;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn6 .liIn_left .bot{
background:#05d1fc;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_left zi{
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_line{
width:58%;
height:0.08rem;
background:rgba(255,255,255,0.5);
border-radius:2000px;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_line .line_lineIn{
width:100%;
height:0.08rem;
background:#f78cf3;
border-radius:100px;
-webkit-animation: widthMove1 2s ease-in-out ;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn2 .liIn_line .line_lineIn{
background:#e7feb8;
-webkit-animation: widthMove2 2s ease-in-out ;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn3 .liIn_line .line_lineIn{
background:#fdea8a;
-webkit-animation: widthMove3 2s ease-in-out ;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn4 .liIn_line .line_lineIn{
background:#8ff9f8;
-webkit-animation: widthMove4 2s ease-in-out ;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn5 .liIn_line .line_lineIn{
background:#d890fa;
-webkit-animation: widthMove5 2s ease-in-out ;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn6 .liIn_line .line_lineIn{
background:#05d1fc;
-webkit-animation: widthMove6 2s ease-in-out ;}
@-webkit-keyframes widthMove1 {
0% {width:0%; }
100% { width:98.5%; }
}
@-webkit-keyframes widthMove2 {
0% {width:0%; }
100% { width:88.5%; }
}
@-webkit-keyframes widthMove3 {
0% {width:0%; }
100% { width:68.5%; }
}
@-webkit-keyframes widthMove4 {
0% {width:0%; }
100% { width:40.5%; }
}
@-webkit-keyframes widthMove5 {
0% {width:0%; }
100% { width:22.5%; }
}
@-webkit-keyframes widthMove6 {
0% {width:0%; }
100% { width:10.5%; }
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .num{
width:17%;
font-family:dig;
padding-left:0.02rem;}
/*左边底部*/
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul{
display:flex;
display: -webkit-flex;
flex-wrap:wrap;
width:100%;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul li{
width:33.3%;
text-align:center;
margin-bottom:0.05rem;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul li .shu{
font-size:0.14rem;
color:rgba(14,253,255,1);
font-family:dig;
padding:0.12rem 0 0.02rem;
font-weight:normal;}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul li .zi{
font-size:0.06rem;
color:#fff;}
/*右边部分*/
.rightMain .rightMain_top{
width:100%;
padding-bottom:0.1rem;
}
.rightMain .rightMain_topIn{
border:0.008rem solid rgba(14,253,255,0.5);
width:100%;
min-height:60px;
position:relative;
padding:0.08rem 0.05rem;
}
.rightMain .rightMain_topIn h3{
font-size:0.08rem;
color:#fff;
margin-bottom:0.05rem;
}
.rightMain .rightMain_topIn .biaoge{
min-height:200px;}
.rightMain .rightMain_bottom{
width:100%;
}
.rightMain .rightMain_bottomIn{
border:0.008rem solid rgba(14,253,255,0.5);
width:100%;
min-height:60px;
position:relative;
padding:0.08rem 0.05rem;
}
.rightMain .rightMain_bottomIn h3{
font-size:0.08rem;
color:#fff;
margin-bottom:0.05rem;
}
/*右下角表格*/
.rightMain .rightMain_bottomIn .biaoge{
min-height:200px;}
.rightMain .rightMain_bottomIn .biaoge_list{
overflow:hidden;
position: relative;}
.rightMain .rightMain_bottomIn .biaoge_list .biaoge_listIn .ul_list{
overflow:hidden;
position: relative;}
.rightMain .rightMain_bottomIn .biaoge_list .biaoge_listIn .ul_listIn{
-webkit-animation: 14s gundong linear infinite normal;
animation: 14s gundong linear infinite normal;
position: relative;}
@keyframes gundong {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, -30vh, 0);
transform: translate3d(0, -30vh, 0);
}
}
.rightMain .rightMain_bottomIn .biaoge_list ul{
display:flex;
display: -webkit-flex;
width:100%;
}
.rightMain .rightMain_bottomIn .biaoge_list .ul_title{
background: linear-gradient(left, rgba(255,255,255,0.1), rgba(255,255,255,0.5), rgba(255,255,255,0.1));
background: -ms-linear-gradient(left, rgba(255,255,255,0.1), rgba(255,255,255,0.5), rgba(255,255,255,0.1));
background: -webkit-linear-gradient(left, rgba(255,255,255,0.1), rgba(255,255,255,0.5), rgba(255,255,255,0.1));
background: -moz-linear-gradient(left, rgba(255,255,255,0.1), rgba(255,255,255,0.5), rgba(255,255,255,0.1));
}
.rightMain .rightMain_bottomIn .biaoge_list .ul_con{
border-bottom:0.008rem solid rgba(14,253,255,0.5);}
.rightMain .rightMain_bottomIn .biaoge_list ul li{
width:20%;
text-align:center;
color:#fff;
font-size:0.06rem;
height:0.2rem;
line-height:0.2rem;}
.rightMain .rightMain_bottomIn .biaoge_list ul li:frist-child{
text-align:left;}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

@ -1,669 +0,0 @@
<!doctype html>
<html>
<head>
<!--更多资源https://gitee.com/iGaoWei/big-data-view -->
<meta charset="utf-8">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>酷炫智能大屏数据中心</title>
<!--大屏-->
<link type="text/css" href="css/public2.css" rel="stylesheet">
<link type="text/css" href="css/icon.css" rel="stylesheet">
<link type="text/css" href="css/index2.css" rel="stylesheet">
<script type="text/javascript">
document.documentElement.style.fontSize = document.documentElement.clientWidth /768*100 + 'px';
</script>
<script src="js/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div class="bg">
<div class="title">HADG数据分析中心<button type="button" class="refresh-button" onclick="location.reload();"></button></div>
<div class="leftMain">
<div class="leftMain_top">
<div id="mytitle"></div>
</div>
<div class="leftMain_middle">
<div class="leftMain_middle_left">
<div class="leftMain_middle_leftIn">
<h3>系统处理信息数量统计图</h3>
<!-- 为ECharts准备一个具备大小宽高的Dom -->
<div class="biaoge" style="width:100%; height:25vh" id="chartmain"></div>
<script type="text/javascript">
//window.onload = function () {
//指定图表的配置项和数据
//};
</script>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
<div class="leftMain_middle_right">
<div class="leftMain_middle_rightIn">
<h3>服务器错误率情况</h3>
<div class="biaoge biaoge_pai" style="width:100%; height:25vh">
<div class="biaoge_paiIn">
<ul>
<div id="mylist"></div>
</ul>
</div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
<div class="leftMain_middle">
<div class="leftMain_middle_left">
<div class="leftMain_middle_leftIn">
<h3>服务器响应时间波动情况</h3>
<div class="biaoge" style="width:100%; height:25vh">
<canvas id="chartmain_zhe"></canvas>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
<div class="leftMain_middle_right">
<div class="leftMain_middle_rightIn">
<h3>服务器存活情况</h3>
<div class="biaoge biaoge_bi" style="width:100%; height:25vh">
<div class="biaoge" style="width:100%; height:30vh" id="chartmain_bing2"></div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
</div>
<di class="rightMain">
<div class="rightMain_top">
<div class="rightMain_topIn">
<h3></h3>
<div class="biaoge" style="width:100%; height:30vh" id="chartmain_bing"></div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
<div class="rightMain_bottom">
<div class="rightMain_bottomIn">
<h3>最近处理消息简报</h3>
<div class="biaoge biaoge_list" style="width:100%; height:36vh">
<div class="biaoge_listIn">
<ul class="ul_title">
<li>服务器名</li>
<li>地区</li>
<li>报文格式</li>
<li>响应时间</li>
</ul>
<div class="ul_list">
<div class="ul_listIn">
<ul class="ul_con">
<li>127.0.0.1</li>
<li>北京</li>
<li>TCP</li>
<li>110ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.2</li>
<li>广州</li>
<li>TCP</li>
<li>150ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.2</li>
<li>广州</li>
<li>TCP</li>
<li>144ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.3</li>
<li>上海</li>
<li>TCP</li>
<li>220ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.1</li>
<li>北京</li>
<li>TCP</li>
<li>70ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.3</li>
<li>上海</li>
<li>TCP</li>
<li>170ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.2</li>
<li>广州</li>
<li>TCP</li>
<li>110ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.3</li>
<li>上海</li>
<li>TCP</li>
<li>310ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.1</li>
<li>北京</li>
<li>TCP</li>
<li>120ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.3</li>
<li>上海</li>
<li>TCP</li>
<li>580ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.2</li>
<li>广州</li>
<li>TCP</li>
<li>110ms</li>
</ul>
<ul class="ul_con">
<li>127.0.0.2</li>
<li>广州</li>
<li>TCP</li>
<li>70ms</li>
</ul>
</div>
</div>
<div style="clear:both;"></div>
</div>
<!--大屏-->
<!--数字增长累加动画-->
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="js/jquery.numscroll.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// var jsonData;
// function a(){
// jsonData='aaaa';
// }
// setInterval(a,1000);
// console.log(jsonData);
//document.addEventListener('DOMContentLoaded', function() {
// 获取表单元素
// window.setInterval(myFunction,5000);
//     function myFunction(){
//         fetch('http://localhost:8080/aaa', {
//             method: 'POST', // 或者 'PUT'
//             headers: {
//                 'Content-Type': 'application/json',
//                 // 如果需要认证添加Authorization头部
//                 // 'Authorization': 'Bearer your_token_here'
//             },
//             body: 'abc' // 将表单数据转换为JSON字符串
//         })
//         .then(response => {return response.json()}) // 转换响应为JSON
//         .then(data => {
//             var jsonData=data;
// console.log(jsonData)
//         })
//     }
// })
var jsonData1={ AveSurRate:0.71,messageCount:2980,//平均存活度
TimeArray:['6.17', '6.18', '6.19', '6.20', '6.21', '6.22', '6.23', '6.24', '6.25', '6.26', '6.27', '6.28', '6.29', '6.30', '7.1'],//系统处理信息数量统计图横轴
DataArray:[220, 182, 191, 234, 290, 330, 310, 123, 442, 321, 90, 149, 210, 122, 150],//系统处理信息数量统计图数据
data1:[//错误率
{value: 0.1, name: '北京'},
{value: 0.6, name: '广州'},
{value: 0.1, name: '长沙'},
{value: 0.2, name: '上海'},
],
data2:[//存活情况
{value: 0.2, name: '良好'},
{value: 0.2, name: '一般'},
{value: 0.3, name: '差'},
{value: 0.3, name: '极差'},
],
data:{
labels: ['16:00', '16:10', '16:20', '16:30', '16:40', '16:50'], // 服务器响应时间波动情况X轴标签
datasets: [//服务器响应时间波动情况数据信息
{
label: '127.0.0.1', // 数据集名称
data: [100, 70, 70, 60, 77, 79], // 数据集数据
},
{
label: '127.0.0.2',
data: [1300, 1300, 1500, 100, 70, 150],
},
{
label: '127.0.0.3',
data: [70, 80, 80, 100, 110, 70],
}]
}
};
var jsonData2={ AveSurRate:0.75,messageCount:3010,//平均存活度
TimeArray:['6.17', '6.18', '6.19', '6.20', '6.21', '6.22', '6.23', '6.24', '6.25', '6.26', '6.27', '6.28', '6.29', '6.30', '7.1'],//系统处理信息数量统计图横轴
DataArray:[220, 182, 191, 234, 290, 330, 310, 123, 442, 321, 90, 149, 210, 122, 350],//系统处理信息数量统计图数据
data1:[//错误率
{value: 0.3, name: '北京'},
{value: 0.4, name: '广州'},
{value: 0.1, name: '长沙'},
{value: 0.2, name: '上海'},
],
data2:[//存活情况
{value: 0.3, name: '良好'},
{value: 0.2, name: '一般'},
{value: 0.1, name: '差'},
{value: 0.2, name: '极差'},
],
data:{
labels: ['16:10', '16:20', '16:30', '16:40', '16:50','17:00'], // 服务器响应时间波动情况X轴标签
datasets: [//服务器响应时间波动情况数据信息
{
label: '127.0.0.1', // 数据集名称
data: [70, 70, 60, 77, 79,80], // 数据集数据
},
{
label: '127.0.0.2',
data: [1300, 1500, 100, 70, 150,170],
},
{
label: '127.0.0.3',
data: [80, 80, 100, 110, 70,100],
}]
}
};
function paintchartmain(jsonData){
console.log('paintchartmain')
var dataAxis = jsonData.TimeArray;
var data = jsonData.DataArray;
var yMax = 500;
var dataShadow = [];
for (var i = 0; i < data.length; i++) {
dataShadow.push(yMax);
}
option = {
title: {
text: '',
subtext: ''
},
grid:{
x:40,
y:40,
x2:20,
y2:20,
},
xAxis: {
data: dataAxis,
axisLabel: {
/*inside: true,*/
interval:0,
textStyle: {
color: '#fff',
fontSize: 12
}
},
axisTick: {
show: false,
},
axisLine: {
show: true,
symbol:['none', 'arrow'],
symbolOffset: 12,
lineStyle:{
color: '#fff',
}
},
z: 10
},
yAxis: {
type: 'value',
name: '条数:条',
axisLine: {
show: true,
symbol: ['none', 'arrow'],
symbolOffset: 12,
lineStyle:{
color: '#fff',
}
},
axisTick: {
show: false
},
axisLabel: {
textStyle: {
color: '#fff',
fontSize: 12
}
}
},
dataZoom: [
{
type: 'inside'
}
],
series: [
{ // For shadow
type: 'bar',
itemStyle: {
color: 'rgba(0,0,0,0.05)'
},
barGap: '-100%',
barCategoryGap: '40%',
data: dataShadow,
animation: false
},
{
type: 'bar',
itemStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{offset: 0, color: '#0efdff'},
{offset: 0.5, color: '#188df0'},
{offset: 1, color: '#188df0'}
]
)
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{offset: 0, color: '#2378f7'},
{offset: 0.7, color: '#2378f7'},
{offset: 1, color: '#0efdff'}
]
)
}
},
data: data
}
]
};
// Enable data zoom when user click bar.
/*var zoomSize = 6;
myChart.on('click', function (params) {
console.log(dataAxis[Math.max(params.dataIndex - zoomSize / 2, 0)]);
myChart.dispatchAction({
type: 'dataZoom',
startValue: dataAxis[Math.max(params.dataIndex - zoomSize / 2, 0)],
endValue: dataAxis[Math.min(params.dataIndex + zoomSize / 2, data.length - 1)]
});
});*/
//获取dom容器
var myChart = echarts.init(document.getElementById('chartmain'));
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
//console.log(jsonData.data);
function paintchartmainbing(jsonData){
var ctx = document.getElementById('chartmain_zhe').getContext('2d');
myChart = new Chart(ctx, {
type: 'line', // 图表类型
data: jsonData.data, // 传递数据
options: {
scales: {
y: {
beginAtZero: false // Y轴是否从0开始
}
},
responsive: true, // 响应式图表
maintainAspectRatio: false // 保持宽高比
}
});
//获取dom容器
option = {
title: {
text: '数据情况统计',
subtext: '',
left: 'right',
textStyle: {
color: '#fff',
fontSize: 12
}
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
// orient: 'vertical',
// top: 'middle',
type: 'scroll',
orient: 'vertical',
right: 10,
top: 40,
bottom: 20,
left: 'right',
data: ['西凉', '益州', '兖州', '荆州', '幽州'],
textStyle: {
color: '#fff',
fontSize: 12
}
},
grid:{
x:'-10%',
y:40,
x2:20,
y2:20,
},
color : [ '#09d0fb', '#f88cfb', '#95f8fe', '#f9f390', '#ecfeb7' ],
series: [
{
type: 'pie',
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: jsonData.data1,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
//获取dom容器
myChart1 = echarts.init(document.getElementById('chartmain_bing'));
// 使用刚指定的配置项和数据显示图表。
myChart1.setOption(option);
setTimeout(function(){
myChart.destroy();
},8000);
}
function paintchartmainbing2(jsonData){
option2 = {
title: {
text: '',
subtext: '',
left: 'right',
textStyle: {
color: '#fff',
fontSize: 12
}
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
// orient: 'vertical',
// top: 'middle',
type: 'scroll',
orient: 'vertical',
right: 10,
top: 40,
bottom: 20,
left: 'right',
data: ['西凉', '益州', '兖州', '荆州', '幽州'],
textStyle: {
color: '#fff',
fontSize: 12
}
},
grid:{
x:'-10%',
y:40,
x2:20,
y2:20,
},
color : [ '#09d0fb', '#f88cfb', '#95f8fe', '#f9f390', '#ecfeb7' ],
series: [
{
type: 'pie',
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: jsonData.data2,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
//获取dom容器
myChart2 = echarts.init(document.getElementById('chartmain_bing2'));
// 使用刚指定的配置项和数据显示图表。
myChart2.setOption(option2);
}
$(".shu1").numScroll();
$(".shu2").numScroll();
$(".shu3").numScroll();
$(".shu4").numScroll();
$(".shu5").numScroll();
$(".shu6").numScroll();
function updateMessageList(data) {
var msgListContainer = document.getElementById('mylist');
msgListContainer.innerHTML = ''; // 清空现有内容
data.forEach(function(item) {
var msgItem = document.createElement('div');
msgItem.className = 'msg_item';
msgItem.innerHTML = `
<li>
<div class="liIn">
<div class="liIn_left"><span class="bot"></span><span class="zi">${item.name}</span></div>
<div class="liIn_line"><div class="line_lineIn" style="width:98.5%;"></div></div>
<p class="num">${item.value}</p>
</div>
</li>
`;
msgListContainer.appendChild(msgItem);
});
}
function updatetitle(jsonData){
let str='';
str+=`
<div class="leftMain_topIn">
<ul>
<li>
<div class="liIn">
<h3>当前系统版本</h3>
<p class="shu"><span class="shu1">1.15</span><i>version</i></p>
<div class="zi"><span class="span1"></span><span></span></div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</li>
<li>
<div class="liIn">
<h3>已连接服务器数量</h3>
<p class="shu"><span class="shu2">5</span><i></i></p>
<div class="zi"><span class="span1"></span><span></span></div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</li>
<li>
<div class="liIn">
<h3>已处理消息总条数</h3>
<p class="shu"><span class="shu3">${jsonData.messageCount}</span><i></i></p>
<div class="zi"><span class="span1"></span><span></span></div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</li>
<li>
<div class="liIn">
<h3>系统活跃度</h3>
<p class="shu"><span class="shu4">${jsonData.AveSurRate}</span><i></i></p>
<div class="zi"><span class="span1"></span><span></span></div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</li>
</ul>
</div>
`;
const el = document.getElementById('mytitle');
        el.innerHTML = str;
}
function paintall()
{
console.log("test");
paintchartmain(jsonData1);
paintchartmainbing(jsonData1);
paintchartmainbing2(jsonData1);
updateMessageList(jsonData1.data1);
updatetitle(jsonData1);
setTimeout(function(){
paintall2();
},8000)
}
function paintall2()
{
console.log("test");
paintchartmain(jsonData2);
paintchartmainbing(jsonData2);
paintchartmainbing2(jsonData2);
updateMessageList(jsonData2.data1);
updatetitle(jsonData2);
}
paintall();
// setInterval(paintall,3000);
/*$(".num2").numScroll({
time:5000
});*/
</script>
<!--大屏-->
</body>
</html>

@ -1,275 +0,0 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export * from './src/echarts';
export * from './src/export';
import './src/component/dataset';
// ----------------------------------------------
// All of the modules that are allowed to be
// imported are listed below.
//
// Users MUST NOT import other modules that are
// not included in this list.
// ----------------------------------------------
// ----------------
// Charts (series)
// ----------------
// All of the series types, for example:
// chart.setOption({
// series: [{
// type: 'line' // or 'bar', 'pie', ...
// }]
// });
import './src/chart/bar';
import './src/chart/boxplot';
import './src/chart/candlestick';
import './src/chart/custom';
import './src/chart/effectScatter';
import './src/chart/funnel';
import './src/chart/gauge';
import './src/chart/graph';
import './src/chart/heatmap';
import './src/chart/line';
import './src/chart/lines';
import './src/chart/map';
import './src/chart/parallel';
import './src/chart/pictorialBar';
import './src/chart/pie';
import './src/chart/radar';
import './src/chart/sankey';
import './src/chart/scatter';
import './src/chart/sunburst';
import './src/chart/themeRiver';
import './src/chart/tree';
import './src/chart/treemap';
// -------------------
// Coordinate systems
// -------------------
// All of the axis modules have been included in the
// coordinate system module below, do not need to
// make extra import.
// `cartesian` coordinate system. For some historical
// reasons, it is named as grid, for example:
// chart.setOption({
// grid: {...},
// xAxis: {...},
// yAxis: {...},
// series: [{...}]
// });
import './src/component/grid';
// `polar` coordinate system, for example:
// chart.setOption({
// polar: {...},
// radiusAxis: {...},
// angleAxis: {...},
// series: [{
// coordinateSystem: 'polar'
// }]
// });
import './src/component/polar';
// `geo` coordinate system, for example:
// chart.setOption({
// geo: {...},
// series: [{
// coordinateSystem: 'geo'
// }]
// });
import './src/component/geo';
// `singleAxis` coordinate system (notice, it is a coordinate system
// with only one axis, work for chart like theme river), for example:
// chart.setOption({
// singleAxis: {...}
// series: [{type: 'themeRiver', ...}]
// });
import './src/component/singleAxis';
// `parallel` coordinate system, only work for parallel series, for example:
// chart.setOption({
// parallel: {...},
// parallelAxis: [{...}, ...],
// series: [{
// type: 'parallel'
// }]
// });
import './src/component/parallel';
// `calendar` coordinate system. for example,
// chart.setOptionp({
// calendar: {...},
// series: [{
// coordinateSystem: 'calendar'
// }]
// );
import './src/component/calendar';
// ------------------
// Other components
// ------------------
// `graphic` component, for example:
// chart.setOption({
// graphic: {...}
// });
import './src/component/graphic';
// `toolbox` component, for example:
// chart.setOption({
// toolbox: {...}
// });
import './src/component/toolbox';
// `tooltip` component, for example:
// chart.setOption({
// tooltip: {...}
// });
import './src/component/tooltip';
// `axisPointer` component, for example:
// chart.setOption({
// tooltip: {axisPointer: {...}, ...}
// });
// Or
// chart.setOption({
// axisPointer: {...}
// });
import './src/component/axisPointer';
// `brush` component, for example:
// chart.setOption({
// brush: {...}
// });
// Or
// chart.setOption({
// tooltip: {feature: {brush: {...}}
// })
import './src/component/brush';
// `title` component, for example:
// chart.setOption({
// title: {...}
// });
import './src/component/title';
// `timeline` component, for example:
// chart.setOption({
// timeline: {...}
// });
import './src/component/timeline';
// `markPoint` component, for example:
// chart.setOption({
// series: [{markPoint: {...}}]
// });
import './src/component/markPoint';
// `markLine` component, for example:
// chart.setOption({
// series: [{markLine: {...}}]
// });
import './src/component/markLine';
// `markArea` component, for example:
// chart.setOption({
// series: [{markArea: {...}}]
// });
import './src/component/markArea';
// `legend` component scrollable, for example:
// chart.setOption({
// legend: {type: 'scroll'}
// });
import './src/component/legendScroll';
// `legend` component not scrollable. for example:
// chart.setOption({
// legend: {...}
// });
import './src/component/legend';
// `dataZoom` component including both `dataZoomInside` and `dataZoomSlider`.
import './src/component/dataZoom';
// `dataZoom` component providing drag, pinch, wheel behaviors
// inside coodinate system, for example:
// chart.setOption({
// dataZoom: {type: 'inside'}
// });
import './src/component/dataZoomInside';
// `dataZoom` component providing a slider bar, for example:
// chart.setOption({
// dataZoom: {type: 'slider'}
// });
import './src/component/dataZoomSlider';
// `dataZoom` component including both `visualMapContinuous` and `visualMapPiecewise`.
import './src/component/visualMap';
// `visualMap` component providing continuous bar, for example:
// chart.setOption({
// visualMap: {type: 'continuous'}
// });
import './src/component/visualMapContinuous';
// `visualMap` component providing pieces bar, for example:
// chart.setOption({
// visualMap: {type: 'piecewise'}
// });
import './src/component/visualMapPiecewise';
// -----------------
// Render engines
// -----------------
// Provide IE 6,7,8 compatibility.
import 'zrender/src/vml/vml';
// Render via SVG rather than canvas.
import 'zrender/src/svg/svg';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,84 +0,0 @@
/*!
* jquery.numscroll.js -- 数字滚动累加动画插件 (Digital rolling cumulative animation)
* version 1.0.0
* 2018-09-22
* author: KevinTseng < 921435247@qq.com@qq.com >
* 文档: https://github.com/chaorenzeng/jquery.numscroll.js.git
* QQ交流群: 739574382
*/
(function($) {
function isInt(num) {
//作用:是否为整数
//返回:true是 false否
var res = false;
try {
if(String(num).indexOf(".") == -1 && String(num).indexOf(",") == -1) {
res = parseInt(num) % 1 === 0 ? true : false;
}
} catch(e) {
res = false;
}
return res;
}
function isFloat(num) {
//作用:是否为小数
//返回:小数位数(-1不是小数)
var res = -1;
try {
if(String(num).indexOf(".") != -1) {
var index = String(num).indexOf(".") + 1; //获取小数点的位置
var count = String(num).length - index; //获取小数点后的个数
if(index > 0) {
res = count;
}
}
} catch(e) {
res = -1;
}
return res;
}
$.fn.numScroll = function(options) {
var settings = $.extend({
'time': 1500,
'delay': 0
}, options);
return this.each(function() {
var $this = $(this);
var $settings = settings;
var num = $this.attr("data-num") || $this.text(); //实际值
var temp = 0; //初始值
$this.text(temp);
var numIsInt = isInt(num);
var numIsFloat = isFloat(num);
var step = (num / $settings.time) * 10; //步长
setTimeout(function() {
var numScroll = setInterval(function() {
if(numIsInt) {
$this.text(Math.floor(temp));
} else if(numIsFloat != -1) {
$this.text(temp.toFixed(numIsFloat));
} else {
$this.text(num);
clearInterval(numScroll);
return;
}
temp += step;
if(temp > num) {
$this.text(num);
clearInterval(numScroll);
}
}, 1);
}, $settings.delay);
});
};
})(jQuery);

@ -154,12 +154,11 @@ min-height: 520px;
overflow: hidden; overflow: hidden;
} }
.lie { .lie {
width: 15%; width: 23%;
display: inline-block; display: inline-block;
font: 13px sans-serif; font: 13px sans-serif;
} }
.lie a { .lie a {
white-space:nowrap;
display: block; display: block;
color: rgb(39, 124, 184); color: rgb(39, 124, 184);
text-align: center; text-align: center;
@ -178,7 +177,7 @@ min-height: 520px;
overflow: hidden; overflow: hidden;
} }
.lia { .lia {
width: 15%; width: 23%;
display: inline-block; display: inline-block;
font: 13px sans-serif; font: 13px sans-serif;
} }

@ -1,202 +0,0 @@
<html>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<head>
<title>模态框示例</title>
<style>
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 2.5% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
.table-container {
margin: auto;
width: 80%;
max-width: 600px; /* 根据需要调整表格的最大宽度 */
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<div>
<canvas id="myChart"></canvas>
</div>
<div class="table-container">
<table>
<caption>响应时间统计</caption>
<tr>
<th>统计指标</th>
<th></th>
</tr>
<tr>
<td>最大响应时间</td>
<td id="maxResponseTime">-</td>
</tr>
<tr>
<td>最小响应时间</td>
<td id="minResponseTime">-</td>
</tr>
<tr>
<td>平均响应时间</td>
<td id="averageResponseTime">-</td>
</tr>
<tr>
<td>错误率</td>
<td id="errorRate">-</td>
</tr>
</table>
</div>
</div>
</div>
</body>
<script>
// 获取按钮和模态框元素
var btn = document.getElementById('openModalBtn');
var modal = document.getElementById('myModal');
var span = document.getElementsByClassName("close")[0];
// 为按钮添加点击事件以打开模态框
modal.style.display = "block";
// 为关闭按钮添加点击事件以关闭模态框
span.onclick = function() {
modal.style.display = "none";
window.history.go(-1); //返回上一页
}
// 在用户点击模态框外部时关闭模态框
// window.onclick = function(event) {
// if (event.target == modal) {
// modal.style.display = "none";
// window.history.go(-1); //返回上一页
// }
// }
//var receiveData={[{"time":"2021.2.19", "responsetime": 10},{"time":"2021.3.19", "responsetime": 10}]};
var receiveData={"servername":"127.0.0.1","DisabledRate": 0.5,
"ResponseTimeArray": [111,110,110,111,111,111],
"Time":["2021.3.19","2021.3.20","2021.3.21","2021.3.22","2021.3.22","2021.3.23"]}
var jsonData = {
"labels": receiveData.Time,
"data": [
{
"label": "响应时间",
"data": receiveData.ResponseTimeArray
},
]
};
// 获取Canvas元素
window.onload=function(){
var ctx = document.getElementById('myChart').getContext('2d');
// 创建折线图
var myChart = new Chart(ctx, {
type: 'line', // 图表类型
data: {
labels:jsonData.labels,
datasets:[{
label:jsonData.data[0].label,
data:jsonData.data[0].data,
backgroundColor: 'rgba(255, 99, 132, 0.2)', // 数据集的背景颜色
borderColor: 'rgba(255, 99, 132, 1)', // 数据集的边框颜色
borderWidth: 1 // 边框宽度
}]
},
options: {
scales: {
y: {
beginAtZero: false // Y轴是否从0开始
}
},
responsive: true, // 响应式图表
maintainAspectRatio: true // 保持宽高比
}
});
};
// 可以添加一个函数来更新图表数据
function updateChartData(newData) {
myChart.data.datasets.forEach((dataset, index) => {
myChart.data.labels = newData.labels;
myChart.data.datasets[index].data = newData.data[index].data;
});
myChart.update();
}
function calculateResponseTimeStats(data) {
const times = data.map(set => set.data);
const flattenedTimes = times.flat();
const maxTime = Math.max(...flattenedTimes);
const minTime = Math.min(...flattenedTimes);
const sumTime = flattenedTimes.reduce((acc, curr) => acc + curr, 0);
const averageTime = sumTime / flattenedTimes.length;
return {
max: maxTime,
min: minTime,
average: averageTime
};
}
// 更新表格中的统计数据
function updateStatsTable(stats,data) {
document.getElementById('maxResponseTime').textContent = stats.max;
document.getElementById('minResponseTime').textContent = stats.min;
document.getElementById('averageResponseTime').textContent = stats.average.toFixed(2);
document.getElementById('errorRate').textContent=data.DisabledRate;
}
// 使用jsonData中的数据更新统计表
const stats = calculateResponseTimeStats(jsonData.data);
updateStatsTable(stats,receiveData);
// 模拟数据更新
setInterval(() => {
// 这里应该根据实际逻辑获取新数据
var newData = {
labels: jsonData.labels,
data: [
// 这里添加新数据点或更新现有数据点
]
};
updateChartData(newData);
}, 1000);
</script>
</html>

File diff suppressed because it is too large Load Diff

@ -1,77 +0,0 @@
GoAccess was designed and developed by Gerardo Orellana <goaccess@prosoftcorp.com>
Special thanks to the following individuals for their great contributions:
* Aaditya Bagga <abchk1234@gmail.com>
* Adam Števko <adam.stevko@gmail.com>
* Adrian <totcha@gazeta.pl>
* Alexander Eifler <github@eifx.de>
* Andreas Sommer <andreas.sommer@ppro.com>
* Andreas Weigel <andreaswe@securepoint.de>
* Andrew Minion <andrew@andrewrminion.com>
* Antonio Terceiro <terceiro@softwarelivre.org>
* Arnie97 <arnie97@gmail.com>
* Aslak Raanes <aslakr@gmail.com>
* Bjørnar Hansen <tilbjornar@gmail.com>
* Bo Cai <charpty@gmail.com>
* Bob Black <git@riblack.com>
* Chilledheart <rwindz0@gmail.com>
* Chris Downs <chris-downs@users.noreply.github.com>
* Christian Hermann <c.hermann@bitbeans.de>
* Christian Moelders <christian.moelders@storeplus.de>
* Christopher Meng <i@cicku.me>
* Daniel (dmilith) Dettlaff <dmilith@me.com>
* Daniel Aleksandersen <code@daniel.priv.no>
* David Geistert <d3f3kt@scripts4u.net>
* Enrique Becerra <kabeza@gmail.com>
* Florian Forster <ff@octo.it>
* Francisco Azevedo <francisco.j.azevedo@gmail.com>
* Frederic Cambus <fcambus@users.sourceforge.net>
* Genki Sugawara <sugawara@cookpad.com>
* Jeffery Wilkins <djcanadianjeff@gmail.com>
* Jeremy Burks <jeremy@zomgwat.com>
* Joe Groocock <me@frebib.net>
* Joe Winett <joe@winett.com>
* Joona <joona.paivahonka@gmail.com>
* Julian Xhokaxhiu <xhokaxhiujulian@gmail.com>
* Justin Mills <justin.mills@utah.edu>
* Kamino Hiroki <37243867+4f8p@users.noreply.github.com>
* Kit Westneat <kit.westneat@gmail.com>
* Maksim Losev <mlosev@beget.ru>
* Mark J. Berger <mark.berger.j@gmail.com>
* Mathieu Aubin <mathieu@zeroserieux.com>
* Mathieu Thoretton <mathieu.thoretton@getyourguide.com>
* Max Christian Pohle <info@entwicklerseite.de>
* Michael Vetter <jubalh@iodoru.org>
* Nicolas <np.pascal@gmail.com>
* Nicolas Le Manchet <nicolas@lemanchet.fr>
* Otto Kekäläinen <otto.kekalainen@seravo.fi>
* Sean Cross <sean@xobs.io>
* Sebastian Wiedenroth <wiedi@frubar.net>
* SjonHortensius <SjonHortensius@users.noreply.github.com>
* Steely Wing <steelywing@users.noreply.github.com>
* Stoyan Dimov <s.dimov@codelogic.eu>
* Stéphane Péchard <stephanepechard@gmail.com>
* Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
* Thomas Gläßle <t_glaessle@gmx.de>
* Tom Samstag <github@modtwo.com>
* Viktor Szépe <viktor@szepe.net>
* Ville Skyttä <ville.skytta@iki.fi>
* Vladimir Pavljuchenkov <spiderx@spiderx.dp.ua>
* Vladimir Pavljuchenkov <spiderx@spiderx.dp.ua>
* Yuri D'Elia <wavexx@thregr.org>
* Yuriy M. Kaminskiy <yumkam@gmail.com>
* abgit <francisco.j.azevedo@gmail.com>
* as0n <n.was.here@gmail.com>
* fqbuild <fqbuild@FutureQuest.net>
* holys <chendahui007@gmail.com>
* kyle sloan <kyle@ifsight.com>
* m-r-r <raybaudroigm@gmail.com>
* mynameiscfed <christopherfederico@gmail.com>
* pravdomil <pravdomil.toman@gmail.com>
* radoslawc <radoslawc@gmail.com>
* radoslawc <radoslawc@gmail.com>
* schoonc <schoonc@users.noreply.github.com>
* wodev <wodev@fischer-net.net>
* woobee <support.developpement@gmail.com>
* zeke <zhenkai0605@gmail.com>

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,705 +0,0 @@
Changes to GoAccess 1.3 - Friday, November 23, 2018
- Added ability to store accumulated processing time into DB_GEN_STATS tcb
file via '--accumulated-time' command line option.
- Added additional Apache status codes to the list.
- Added a few feed readers to the list.
- Added 'Android 8 Oreo' to the list of OSs.
- Added 'Android Pie 9' to the list of OSs.
- Added --anonymize-ip command line option to anonymize ip addresses.
- Added --browsers-file command line option to load a list of crawlers from a
text file.
- Added byte unit (PiB) to C formatter and refactored code.
- Added byte unit (PiB) to JS formatter.
- Added Chinese translation (i18n).
- Added French translation (i18n).
- Added '%h' date specifier to the allowed date character specifiers.
- Added "HeadlessChrome" to the list of browsers.
- Added --hide-referer command line option to hide referers from report.
- Added HTTP status code 429 (TOO MANY REQUESTS).
- Added IGNORE_LEVEL_PANEL and IGNORE_LEVEL_REQ definitions.
- Added --ignore-referer-report command line option to hide referers from
output.
- Added Japanese translation (i18n).
- Added macOS 10.14 Mojave to the list of OSs.
- Added "Mastodon" user-agent to the list of crawlers/unix-like.
- Added new fontawesome icons and use angle arrows in HTML paging.
- Added new purple theme to HTML report and default to it.
- Added --no-parsing-spinner command line option to switch off parsing
spinner.
- Added .ogv and ogg static file extension (ogg video, Ogg Vorbis audio).
- Added OS X version numbers when outputting with --real-os.
- Added parsing mechanism in an attempt capture more bots and to include
unspecified bots/crawlers.
- Added --pidfile command line option to the default config file.
- Added Spanish translation (i18n).
- Added SSL support for Docker goaccess build.
- Added support to the WebSocket server for openssl-1.1*.
- Added the ability to show/hide a chart per panel in the HTML report.
- Added transparency to the navigation bar of the HTML report.
- Added "WhatsApp" user-agent to the list of crawlers.
- Changed default db folder so it adds the process id (PID). --db-path is
required now when using --load-from-disk.
- Changed Dockerfile to build from the current source.
- Changed 'hits' to be right-aligned on TUI.
- Changed to use faster slide animations on HTML report.
- Changed wording from 'Bandwidth' to the proper term 'Tx. Amount'.
- Ensure database filenames used by btree are less predictable.
- Ensure HTML templates, CSS and JS files are minified when outputting
report.
- Ensure key phrases from Google are added even when https is used.
- Ensure live report updates data & charts if tab/document has focus.
- Ensure multiple 'Yandex' crawlers are properly parsed.
- Ensure Safari has priority over most crawlers except the ones that are
known to have it.
- Ensure the request protocol on its own is properly parsed.
- Ensure the right number of tests are performed against the given log.
- Ensure user configuration is parsed first when available.
- Ensure wss:// is used when connecting via HTTPS.
- Ensure XFF parser takes into account escaped braces.
- Fixed a regression where fifo-in/out would fail with ENXIO.
- Fixed a regression where it would return EXIT_FAILURE on an empty log.
- Fixed a (ssh) pipeline problem with fgetline()/fgets() when there is a race
for data on stdin.
- Fixed broken X-Forwarded-For (XFF) %~ specifier in certain parsing cases.
- Fixed conf.filenames duplication problem if logs are via pipe.
- Fixed float percent value on JSON/HTML output for locales using decimal comma.
- Fixed issue where it was not possible to establish a Web Socket connection
when attempting to parse and extract HTTP method.
- Fixed issue where log formats with pipe delimiter were not propely parsed.
- Fixed memory leak after config file path has been set (housekeeping).
- Fixed memory leak when adding host to holder introduced in c052d1ea.
- Fixed possible memory leak when hiding specific referrers.
- Fixed several JS jshint warnings.
- Fixed sudo installs on TravisCI.
- Fixed UNDEFINED time range in HTML report when VISITORS panel was ignored.
- Fixed unnecessary closing span tags from template.
- Fixed use-after-free when two color items were found on color_list.
Changes to GoAccess 1.2 - Tuesday, March 07, 2017
- Added a Dockerfile.
- Added Amazon S3 bucket name as a VirtualHost (server block).
- Added a replacement for GNU getline() to dynamically expand line buffer
while maintaining real-time output.
- Added --daemonize command line option to run GoAccess as daemon.
- Added several improvements to the HTML report on small-screen devices.
- Added option to the HTML report to auto-hide tables on small-screen
devices.
- Added --process-and-exit command line option to parse log and exit.
- Added several feed readers to the list of browsers.
- Added "-" single dash per convention to read from the standard input.
- Added support for MaxMind GeoIP2.
- Added the ability to read and follow from a pipe such as
"tail -f access.log | goaccess -"
- Added the ability to specify multiple logs as input sources, e.g.:
"goaccess access.log access.log.1" while maintaining real-time output.
- Added time unit (seconds) to the processed time label in the HTML/terminal
output.
- Added visitors' percent column to the terminal dashboard.
- Changed D3 charts to dim Y-axis on mouseover.
- Changed D3 charts to reflect HTML column sort.
- Changed D3 charts to render only if within the viewport. This improves the
overall real-time HTML performance.
- Changed HTML report tables to render only if within the viewport.
- Changed percentage calculation to be based on the total within each panel.
- Ensure start/end dates are updated real-time in the HTML output.
- Ensure "window.location.hostname" is used as the default WS server host.
In most cases, this should avoid the need for specifying "--ws-url=host".
Simply using "--real-time-html" should suffice.
- Fixed issue on HTML report to avoid outputting scientific notation for all
byte sizes.
- Fixed integer overflow when calculating bar graph length on terminal
output.
- Fixed issue where global config file would override command line arguments.
- Fixed issue where it wouldn't allow loading from disk without specifying a
file when executed from the cron.
- Fixed issue where parser couldn't read some X-Forwarded-For (XFF) formats.
Note that this breaks compatibility with the original implementation of
parsing XFF, but at the same time it gives much more flexibility on different
formats.
- Fixed issue where specifying fifo-in/out wouldn't allow HTML real-time
output.
- Fixed issue where the wrong number of parsed lines upon erroring out was
displayed.
- Fixed issue where the WebSocket server prevented to establish a connection
with a client due to invalid UTF-8 sequences.
- Fixed percent issue when calculating visitors field.
- Updated the list of crawlers.
Changes to GoAccess 1.1.1 - Wednesday, November 23, 2016
- Added data metric's "unique" count on each panel to the JSON/HTML outputs.
- Changed D3 bar charts to use .rangeBands and avoid extra outer padding.
- Fixed mouseover offset position issue on D3 bar charts.
- Fixed possible heap overflow when an invalid status code was parsed and
processed. This also ensures that only valid HTTP status codes are parsed
>=100 or <= 599.
- Fixed sluggish D3 chart re-rendering by changing how x-axis labels are
displayed in the HTML report.
Changes to GoAccess 1.1 - Tuesday, November 08, 2016
- Added a new layout to the HTML report and additional settings and changes.
- Added --crawlers-only command line option to display crawlers/bots only.
- Added --fifo-in and --fifo-out command line options to set websocket FIFO
reader/writer.
- Added --no-html-last-updated command line option.
- Added --num-tests command line option.
- Added --html-prefs command line option to to set default preferences for
the HTML report.
- Added "Amazon S3" Log Format to the list of predefined options.
- Added "Android 7.1 Nougat" to the list of OSs.
- Added "Android Marshmallow 6.0.1" to the list of OSs.
- Added "Android Nougat 7.0" to the list of OSs.
- Added "Feed Wrangler" to the list of feeds.
- Added "Go-http-client" to the list of browsers.
- Added "MicroMessenger" (WeChat) to the list of browsers.
- Added "SemrushBot" to the list of crawlers.
- Added "Remote User" panel to capture HTTP authentication requests. Use %e
within the log-format variable to enable this panel.
- Added tebibyte unit to the byte to string function converter.
- Added the ability to parse reverse proxy logs that have multiple IPs. This
adds the ability to parse the "X-Forwarded-For" field in a reverse proxy
setup.
- Added the ability to show which token didn't match log/date/time pattern.
This also ensures that in the absence of data, its output is not treated as
error but instead it produces an empty report.
- Added the ability to specify a WebSocket protocol (ws|wss) through
--ws-url.
- Added the request query string to the W3C format.
- Added TLS/SSL support to the HTML real-time report.
- Changed browser classification for Google Cloud Clients.
- Changed how "Darwin" OS was reported to display AppName instead.
- Changed default W3C log format to use the URL path instead of full request.
- Changed HTML default number of items on each table to 7.
- Changed request parser to allow empty query strings.
- Changed default HTML output theme to darkBlue.
- Ensure every version of iOS is broken down under the OS panel.
- Ensure latest JSON data is fast-forwarded when connection is opened.
GoAccess now sends the latest JSON data to the client as soon as the
WebSocket connection is opened.
- Ensure localStorage is supported and enabled in the HTML report
- Ensure unknown coutries/continents are listed.
- Fixed D3 chart width overflow issue on Edge.
- Fixed integer to string key conversion for unique visitors. This fixes the
issue where resulting keys would collide with existing keys and thus not
keeping the right visitors count on certain panels.
- Fixed memory leak when unable to URL decode %q specifier.
- Fixed memory leak when unable to URL decode %U specifier.
- Fixed month name abbreviation on app.js.
- Fixed percentage integer overflow with large numbers on 32bits platforms.
- Fixed percent calculation due to integer division rounding to zero.
- Fixed possible code injection when outputting an HTML report.
- Fixed segfault when using options -H or -M without an argument.
- Removed timestamp from the HTML report title tag.
Changes to GoAccess 1.0.2 - Tuesday, July 05, 2016
- Added minor changes to the HTML report stylesheet.
- Added the ability to specify the WebSocket port within --ws-url.
- Added the proper byte swap functions used by Sun Solaris.
- Added the proper default --http-method/protocol values on the config file.
- Changed bar transition to scale delay dynamically to the length of the
dataset.
- Fixed build issue on platforms lacking of open_memstream() by refactoring
the JSON module to use its own memory buffer.
- Fixed issue where the server wouldn't send cached buffer to slow clients.
- Fixed OS X build check of ncursesw.
- Implemented a throttle mechanism for slow clients to avoid caching too much
data on the server-side.
- Removed flickering on D3 line and bar chart redraw.
Changes to GoAccess 1.0.1 - Friday, June 17, 2016
- Added Android version number along with the codename when using --real-os,
e.g., "Lollipop 5.1".
- Added some missing headers and function checks to configure.ac.
- Fixed a regression where it wouldn't allow abbreviated date and time
formats such as %F or %T.
- Fixed build issues on systems running GLIBC older than 2.9, such as RHEL <= 5.
- Fixed issue where it wouldn't send the whole buffer to a socket causing the
real-time-html WebSocket server to progressively consume a lot more memory.
- Fixed memory leak when using getline and follow mode enabled.
- Fixed some buffer initialization issues on read_line() and
perform_tail_follow().
- Fixed uint types in sha1 files.
Changes to GoAccess 1.0 - Thursday, June 09, 2016
- Added --enable-panel=<PANEL> command line option to display the given
module.
- Added --json-pretty-print command line option to output pretty json.
- Added --log-format=<format> command-line shortcuts for standard log
formats.
- Added --origin command line option to match the origin WebSocket header.
- Added --output=<file.[html|csv|json]> as a shortcut to --output-format.
- Added a complete real-time functionality to the HTML output.
- Added an option to set the max number of items to show per panel.
- Added D3 Visualziations to the HTML dashboard.
- Added metadata metrics to the each of the panels (JSON output)
- Added option to specify time distribution specificity.
- Added the ability to download a JSON file from the HTML report.
- Added the ability to output multiple formats on a single log parse.
- Added the ability to set the date specificity in hours.
- Added the ability to sort all HTML tables on all panels.
- Added the ability to specify a custom CSS and JS file to the HTML report.
- Added user-agents to the JSON output per each host.
- Added "Vivaldi" to the list of browsers.
- Bootstrapify the HTML dashboard.
- Changed configure.ac to use LDFLAGS instead of CFLAGS where applicable.
- Changed default terminal color scheme to 256 Monokai if terminal supports 256 colors.
- Changed GoAccess license to The MIT License (MIT)
- Changed the visitors panel to display its dates continuously instead of top.
- Default to 256 Monokai color scheme if terminal supports 256 colors.
- Default to display HTTP method/protocol (if applicable).
- Display the children's Max. T.S. as the parent's top Max. T.S.
- Ensure the parent's Avg. T.S. displays parent's Cum. T.S. over parent's Hits.
- Fixed color issue when switching from the color scheme dialog.
- Fixed cross platform build issue when ncurses is built with and without
termlib=tinfo.
- Fixed curses header window issue where it wouldn't clear out on small
window sizes.
- Fixed issue where tail mode wouldn't parse full lines using getline().
- Fixed minor background color issue when using ncurses 6.
- Fixed possible division by zero when calculating percentage.
- Fixed singly link list node removal.
- Fixed still reachable memory leak on GeoIP cleanup (geoip legacy >= 1.4.7).
- Fixed various Valgrind's still reachable memory leaks.
- Removed -Wredundant-decls.
Changes to GoAccess 0.9.8 - Monday, February 29, 2016
- Added a more complete list of static extensions to the config file.
- Added "Android 6.0 Marshmallow" to the list of OSs.
- Added --no-tab-scroll command line option to disable scroll through panels
on TAB.
- Added the first and last log dates to the overall statistics panel.
- Ensure GoAccess links correctly against libtinfo.
- Ensure static content is case-insensitive verified.
- Fixed bandwidth overflow issue (numbers > 2GB on non-x86_64 arch).
- Fixed broken HTML layout when html-method/protocol is missing in config file.
- Refactored parsing and display of available modules/panels.
Changes to GoAccess 0.9.7 - Monday, December 21, 2015
- Added "Squid native" log format to the config file.
- Fixed integer overflow when getting total bandwidth using the on-disk
storage.
- Fixed issue where a timestamp was stored as date under the visitors panel.
- Fixed issue where config dialog fields were not cleared out on select.
- Fixed issue where "Virtual Hosts" menu item wasn't shown in the HTML sidebar.
Changes to GoAccess 0.9.6 - Tuesday, October 27, 2015
- Added --dcf command line option to view the default config file path.
- Added --ignore-status the ability to ignore parsing status codes.
- Added "Darwin" to the list of OSs.
- Fixed segfault when appending data to a log (follow) without virtualhosts.
Changes to GoAccess 0.9.5 - Thursday, October 22, 2015
- Added major performance improvements to the default storage when parsing and
storing data (~%44 less memory, ~37% faster).
- Added the ability to parse virtual hosts and a new panel to display metrics
per virtual host.
- Added the ability to parse HTTP/2 requests.
- Added the ability to use GNU getline() to parse full line requests.
- Added the ability to output debug info if a log file is specified, even
without --enable-debug.
- Added OS X "El Capitan".
- Added WebDav HTTP methods and HTTP status from RFC 2518 and RFC 3253.
- Fixed detection of some Googlebots.
- Fixed issue where time served metrics were not shown when loading persisted
data.
- Fixed linker error on OSX: ld: library not found for -lrt.
- Fixed percentage on the HTML output when excluding IPs.
- Removed GLib dependency and refactored storage functionality. By removing
this dependency, GoAccess is able to store data in a more efficient manner,
for instance, it avoids storing integer data as void* (generic typing), thus
greatly improving memory consumption for integers.
Changes to GoAccess 0.9.4 - Tuesday, September 08, 2015
- Added --all-static-files command line option to parse static files
containing a query string.
- Added --invalid-requests command line option to log invalid requests to a file.
- Added additional overall metric - total valid requests.
- Added "%~" specifier to move forward through a log string until a non-space
char is found.
- Added the ability to parse native Squid access.log format.
- Fixed a few issues in the configuration script.
- Fixed inability to parse color due to a missing POSIX extension.
"ERR:Invalid bg/fg color pairs"
Changes to GoAccess 0.9.3 - Wednesday, August 26, 2015
- Added --no-column-names command line option to disable column name metrics.
- Added a default color palette (Monokai) to the config file.
- Added AWS Elastic Load Balancing to the list of predefined log/date/time
formats.
- Added CloudFlare status codes.
- Added column headers for every enabled metric on each panel.
- Added cumulative time served metric.
- Added "DragonFly" BSD to the list of OSs.
- Added maximum time served metric (slowest running requests).
- Added "Slackbot" to the list of crawlers/browsers.
- Added the ability to parse the query string specifier "%q" from a log file.
- Added the ability to process logs incrementally.
- Added the ability to set custom colors on the terminal output.
- Disabled REFERRERS by default.
- Ensure bandwidth metric is displayed only if %b specifier is parsed.
- Fixed issue where the --sort-panel option wouldn't sort certain panels.
- Fixed several compiler warnings.
- Set predefined static files when no config file is used.
- Updated "Windows 10" user agent from 6.4 (wrong) to 10.0.(actual)
Changes to GoAccess 0.9.2 - Monday, July 06, 2015
- Added ability to fully parse browsers that contain spaces within a token.
- Added multiple user agents to the list of browsers.
- Added the ability to handle time served in milliseconds as a decimal number
`%L`.
- Added the ability to parse a timestamp in microseconds.
- Added the ability to parse Google Cloud Storage access logs.
- Added the ability to set a custom title and header in the HTML report.
- Added "%x" as timestamp log-format specifier.
- Ensure agents" hash table is destroyed upon exiting the program.
- Ensure "Game Systems" are processed correctly.
- Ensure visitors panel header is updated depending if crawlers are parsed or
not.
- Fixed issue where the date value was set as time value in the config
dialog.
- Fixed memory leak in the hits metrics when using the in-memory storage
(GLib).
Changes to GoAccess 0.9.1 - Tuesday, May 26, 2015
- Added --hl-header command line option to highlight active panel.
- Added "Applebot" to the list of web crawlers.
- Added "Microsoft Edge" to the list of browsers.
- Added additional Nginx-specific status codes.
- Ensure dump_struct is used only if using __GLIBC__.
- Ensure goaccess image has an alt attribute on the HTML output for valid
HTML5.
- Ensure the config file path is displayed when something goes wrong (FATAL).
- Ensure there is a character indicator to see which panel is active.
- Fixed Cygwin compile issue attempting to use -rdynamic.
- Fixed issue where a single IP did not get excluded after an IP range.
- Fixed issue where requests showed up in the wrong view even when
--no-query-string was used.
- Fixed issue where some browsers were not recognized or marked as "unknown".
- Fixed memory leak when excluding an IP range.
- Fixed overflows on sort comparison functions.
- Fixed segfault when using on-disk storage and loading persisted data with -a.
- Removed keyphrases menu item from HTML output.
- Split iOS devices from Mac OS X.
Changes to GoAccess 0.9 - Thursday, March 19, 2015
- Added --geoip-database command line option for GeoIP Country/City IPv6.
- Added "Windows 10 (v6.4)" to the real windows user agents.
- Added ability to double decode an HTTP referer and agent.
- Added ability to sort views through the command line on initial load.
- Added additional data values to the backtrace report.
- Added additional graph to represent the visitors metric on the HTML output.
- Added AM_PROG_CC_C_O to configure.ac
- Added "Android Lollipop" to the list of operating systems.
- Added "average time served" metric to all panels.
- Added "bandwidth" metric to all panels.
- Added command line option to disable summary metrics on the CSV output.
- Added numeric formatting to the HTML output to improve readability.
- Added request method specifier to the default W3C log format.
- Added the ability to ignore parsing and displaying given panel(s).
- Added the ability to ignore referer sites from being counted. A good case
scenario is to ignore own domains. i.e., owndomain.tld. This also allows
ignoring hosts using wildcards. For instance, *.mydomain.tld or www.mydomain.*
or www?.mydomain.tld
- Added time/hour distribution module. e.g., 00-23.
- Added "visitors" metrics to all panels.
- Changed AC_PREREQ macro version so it builds on old versions of autoconf.
- Changed GEOIP database load to GEOIP_MEMORY_CACHE for faster lookups.
- Changed maximum number of choices to display per panel to 366 fron 300.
- Ensure config file is read from home dir if unable to open it from
%sysconfdir% path.
- Fixed array overflows when exceeding MAX_* limits on command line options.
- Fixed a SEGFAULT where sscanf could not handle special chars within the
referer.
- Fixed character encoding on geolocation output (ISO-8859 to UTF8).
- Fixed issue on wild cards containing "?" at the end of the string.
- Fixed issue where a "Nothing valid to process" error was triggered when the
number of invalid hits was equal to the number of valid hits.
- Fixed issue where outputting to a file left a zero-byte file in pwd.
- Improved parsing of operating systems.
- Refactored log parser so it allows with ease the addition of new modules.
This also attempts to decouple the core functionality from the rendering
functions. It also gives the flexibility to add children metrics to root
metrics for any module. e.g., Request A was visited by IP1, IP2, IP3, etc.
- Restyled HTML output.
Changes to GoAccess 0.8.5 - Sunday, September 14, 2014
- Fixed SEGFAULT when parsing a malformed request that doesn't have HTTP
status.
Changes to GoAccess 0.8.4 - Monday, September 08, 2014
- Added --444-as-404 command line option to handle nginx non-standard status
code 444 as 404.
- Added --4xx-to-unique-count command line option to count client errors (4xx)
to the unique visitors count. Now by default it omits client errors (4xx)
from being added to the unique visitors count as they are probably not welcomed
visitors. 4xx errors are always counted in panels other than visitors, OS &
browsers.
- Added and updated operating systems, and browsers.
- Added excluded IP hits count to the general statistics panel on all reports.
- Added HTTP nonstandard code "444" to the status code list.
- Fixed compile error due to missing include <sys/types.h> for type
off_t (gcc 4.1).
- Fixed issue when excluding IPv4/v6 ranges.
- Removed request status field restriction. This allows parsing logs that
contain only a valid date, IPv4/6 and host.
Changes to GoAccess 0.8.3 - Monday, July 28, 2014
- Fixed SEGFAULT when parsing a CLF log format and using --ignore-crawlers.
- Fixed parsing conflict between some Opera browsers and Chrome.
- Fixed parsing of several feed readers that are Firefox/Safari-based.
- Fixed Steam detection.
- Added Huawei to the browser's list and removed it from the OS's list.
Changes to GoAccess 0.8.2 - Monday, July 20, 2014
- Added --version command line option.
- Added --ignore-crawlers command line option to ignore crawlers.
- Added ability to parse dates containing whitespaces in between,
e.g., "Jul 15 20:13:59" (syslog format).
- Added a variety of browsers, game systems, feed readers, and podcasts.
- Added missing up/down arrows to the help section.
- Added the ability to ignore multiple IPv4/v6 and IP ranges.
- Added the PATCH method according to RFC 5789.
- Fixed GeoLocation percent issue for the JSON, CSV and HTML outputs.
- Fixed memory leak when excluding one or multiple IPs.
Changes to GoAccess 0.8.1 - Monday, June 16, 2014
- Added ability to add/remove static files by extension through the config
file.
- Added ability to print backtrace on segmentation fault.
- Escaped JSON strings correctly according to [RFC4627].
- Fixed encoding issue when extracting keyphrases for some HTTP referers.
- Fixed issue where HTML bar graphs were not shown due to numeric locale.
- Fixed issue with URIs containing "\r?\n" thus breaking the corresponding
output.
- Make sure request string is URL decoded on all outputs.
Changes to GoAccess 0.8 - Tuesday, May 20, 2014
- Added APT-HTTP to the list of browsers.
- Added data persistence and ability to load data from disk.
- Added IE11 to the list of browsers.
- Added IEMobile to the list of browsers.
- Added multiple command line options.
- Added Nagios check_http to the list of browsers.
- Added parsing progress metrics - total requests / requests per second.
- Added the ability to parse a GeoLiteCity.dat to get the city given an IPv4.
- Changed the way the configuration file is parsed. This will parse all
configuration options under ~/.goaccessrc or the specified config file and
will feed getopt_long with the extracted key/value pairs. This also allows the
ability to have comments on the config file which won't be overwritten.
- Ensure autoconf determines the location of ncurses headers.
- Fixed issue where geo_location_data was NULL.
- Fixed issue where GoAccess did not run without a tty allocated to it.
- Fixed potential memory leak on --log-file realpath().
- Fixed Solaris build errors.
- Implemented an on-memory hash database using Tokyo Cabinet. This
implementation allows GoAccess not to rely on GLib's hash table if one is
needed.
- Implemented large file support using an on-disk B+ Tree database. This
implementation allows GoAccess not to hold everything in memory but instead
it uses an on-disk B+ Tree database.
- Trimmed leading and trailing whitespaces from keyphrases module.
Changes to GoAccess 0.7.1 - Monday, February 17, 2014
- Added --no-color command line option to turn off color output.
- Added --real-os command line option to get real OS names, e.g.,
"Android, Windows, Mac".
- Added ability to log debug messages to a file.
- Added ability to parse tab-separated log format strings.
- Added ability to support terminals without colors.
- Added command line option to append HTTP method to request.
- Added command line option to append HTTP protocol to request.
- Added long options to command-line.
- Added missing "Win 9x 4.90" (Windows Me) user-agent.
- Added missing Windows RT user-agent.
- Ensure mouse click does not reset expanded module if it is the same.
- Fixed Amazon CloudFront tab-separated log format.
- Fixed "FreeBSD style" ncursesw built into system.
- Fixed HTML report issue where data cell would not wrap.
- Fixed issue when isatty() could not find a valid file descriptor.
- Fixed SymbianOS user-agent and retrieve its version.
Changes to GoAccess 0.7 - Monday, December 15, 2013
- Added a command line option to ignore request query strings.
- Added additional compiler flags & fixed several warnings.
- Added additional static file extensions.
- Added country per IP to HOSTS module (HTML & JSON).
- Added DEBUG mode to Makefile & -O2 to default release.
- Added GEOLOCATION report to all outputs - includes continents/countries.
- Added IP resolver to HTML and JSON output.
- Added module numbers to each module header.
- Added the ability to output JSON and CSV.
- Added Windows NT 6.3 (Win 8.1) to the list.
- Fixed buffer overflow issue with realpath.
- New HTML report - HTML5 + CSS styles.
- Properly split request line into the three request modules.
Changes to GoAccess 0.6.1 - Monday, October 07, 2013
- Added active module indication by name.
- Added additional crawlers to the list.
- Added custom configuration file option.
- Added human-readable string when unable to open log.
- Added missing include when compiling on OSX 10.6.
- Added optional mouse support to the main dashboard.
- Added the ability to select active module by number (keys).
- Added the rest of HTTP methods according to RFC2616.
- Changed referring site sscanf format to process multiple URLs.
- Changed the default color scheme to monochrome.
- Fixed issue where %T was not processing floating-point numbers.
- Fixed percentage issue for browsers and os modules.
- Fixed SIGSEGV when reading from stdin to stdout.
- Improved performance when expanding a module.
- Reduced memory consumption by decreasing number of dns threads.
- Removed ^UP/^DOWN due to a key mapping conflict.
Changes to GoAccess 0.6 - Monday, July 15, 2013
- Added a bunch of minor fixes and changes.
- Added and updated list of browsers and operating systems.
- Added a predefined log format/date for the Amazon CloudFront (Download
Distribution).
- Added parsing/processing indicators.
- Added the ability to independently sort each module.
- Added the ability to search across the whole dashboard with the option to
use regular expressions.
- Config window now accepts [ENTER] to continue or F10.
- Fixed issue where Opera +15 was identified as Chrome.
- Implemented the ability to parse the time taken to serve the request, in
microseconds and seconds.
- Improved memory usage and better performance in general.
- Moved away from the original pop-up UI to a new expandable dashboard
allowing data to be processed in real-time.
- Sanitized HTML output with html entities for special chars.
- Updated the hosts module so it shows the reverse DNS as a sub node.
Changes to GoAccess 0.5 - Monday, June 04, 2012
- Added ability to output a full stats report to a file.
- Added a key shortcut to scroll top/bottom.
- Added a new include sys/socket.h - BSD
- Added support for IPv6
- Added the ability to parse a custom format string.
- Fixed google cache key-phrases.
- Fixed issue on empty Google query strings.
- Fixed issue on Opera agents where version was not recognized correctly.
- Fixed other minor fixes and changes.
Changes to GoAccess 0.4.2 - Monday, January 03, 2011
- Added UTF-8 support. Now it should handle properly wide-character/UTF-8.
Run ./configure --enable-utf8
- Fixed a minor bug when adding monthly totals on visitors subwin.
- Removed -lrt since GoAccess does not link to librt. (OS X doesn't include
librt)
Changes to GoAccess 0.4.1 - Monday, December 13, 2010
- Added more flexibility when resizing the terminal. Should work fine with
the standard 80x24.
- Added the ability to pass a flag to ./configure so GeoIP can be enabled if
needed.
- Implemented a pipeline from stdin, so the input doesn't have to be only a
file.
Changes to GoAccess 0.4 - Tuesday, November 30, 2010
- Added graphs to the unique_visitors subwin.
- Implemented bandwidth per day, and host.
- Implemented list of agents for specific hosts.
- Rewrote hash tables iterative code to avoid the use of GHashTableIter, this
way it works with all GLib > 2.0.0.
- Various bug fixes and code cleanups (mainly in the subwin modules).
Changes to GoAccess 0.3.3 - Monday, September 27, 2010
- Changed tarball's filename.
- Fixed a request size parsing issue. Due to malformed syntax on the HTTP
protocol, bandwidth was reset to 0. Ex. "HEAD /" 400 20392
- Fixed a segfault when goaccess was executed without any options but with an
additional unknown argument.
Changes to GoAccess 0.3.2 - Thursday, September 09, 2010
- Fixed an agent parsing issue. As a result, operating systems were not
properly counted.
Changes to GoAccess 0.3.1 - Friday, September 03, 2010
- Added a color scheme implementation
Changes to GoAccess 0.3 - Sunday, August 29, 2010
- Added a counter for total requests since initial parse was implemented
- Added a more detailed and comprehensive browser and os report
- Added bandwidth details for requested files
- Added percentage details on modules 2, 3, 4, 5, 10, 11
- Code cleanups
- Fixed a potential segmentation fault when resizing main window
- Fixed a segmentation fault on pop-up window search if haystack was null
- Fixed invalid entries when parsing status codes
- Implemented a real support for LFS - Handles files larger than 2 GiB on
32-bit systems
- Implemented support for "vhost_combined" log format
- Changed position of data/graphs depending on # of hits
Changes to GoAccess 0.2 - Sunday, July 25, 2010
- Added a keyphrases report coming from Google search engine. This includes,
raw, cache, and translation queries.
- Fixed a memory leak when invalid entries were parsed
- Fixed a potential buffer overflow.
- Implemented real-time statistics (RTS). Data will be appended as the log
file grows. Equivalent to "tail -f" on Unix systems
- Implemented screen resize functionality
- Simpliflied creation of the "unique visitors" hash-key.
- Simpliflied the "process_unique_data" function
- Various small speed increases & code cleanup
Changes to GoAccess 0.1.2 - Monday, July 12, 2010
- Fixed a segmentation fault when parsing logs with unusual request type. Ex.
"GET HTTP/1.1 HTTP/1.1"
Changes to GoAccess 0.1.1 - Saturday, July 10, 2010
- Added an enhanced error handling
- Added an extra macro on configure.ac to check against GHashTableIter.
./configure might not check for glib 2.16 that introduced "GHashTableIter".
- Added Glibc LFS
- Cleaned up code a little bit
- Fixed a segmentation fault when displaying the help text on x86_64.
- Fixed assignments in conditions. In case the assignment is actually intended
put extra parenthesis around it. This will shut GCC (and others) up.
- Fixed casts associated with "g_hash_table_iter_next".
- Fixed comparison between signed and unsigned integer types.
- Fixed function declarations.
- Fixed includes.
- Fixed two format strings. (If the error was ever triggered, it'd most
likely lead to a segfault)
Changes to GoAccess 0.1 - Tuesday, July 06, 2010
- Initial release 0.1

@ -1,370 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

File diff suppressed because it is too large Load Diff

@ -1,219 +0,0 @@
#AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = goaccess
AUTOMAKE_OPTIONS = subdir-objects
dist_noinst_DATA = \
resources/tpls.html \
resources/css/app.css \
resources/css/bootstrap.min.css \
resources/css/fa.min.css \
resources/js/app.js \
resources/js/charts.js \
resources/js/d3.v3.min.js \
resources/js/hogan.min.js
noinst_PROGRAMS = bin2c
bin2c_SOURCES = src/bin2c.c
BUILT_SOURCES = \
tpls.h \
bootstrapcss.h \
facss.h \
appcss.h \
d3js.h \
hoganjs.h \
chartsjs.h \
appjs.h
CLEANFILES = \
src/tpls.h \
src/bootstrapcss.h \
src/facss.h \
src/appcss.h \
src/d3js.h \
src/hoganjs.h \
src/chartsjs.h \
src/appjs.h \
resources/tpls.html.tmp \
resources/css/bootstrap.min.css.tmp \
resources/css/fa.min.css.tmp \
resources/css/app.css.tmp \
resources/js/d3.v3.min.js.tmp \
resources/js/hogan.min.js.tmp \
resources/js/charts.js.tmp \
resources/js/app.js.tmp
# Tpls
tpls.h: bin2c$(EXEEXT) resources/tpls.html
if HAS_SEDTR
cat resources/tpls.html | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/tpls.html.tmp
./bin2c resources/tpls.html.tmp src/tpls.h tpls
else
./bin2c resources/tpls.html src/tpls.h tpls
endif
# Bootstrap
bootstrapcss.h: bin2c$(EXEEXT) resources/css/bootstrap.min.css
if HAS_SEDTR
cat resources/css/bootstrap.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/bootstrap.min.css.tmp
./bin2c resources/css/bootstrap.min.css.tmp src/bootstrapcss.h bootstrap_css
else
./bin2c resources/css/bootstrap.min.css src/bootstrapcss.h bootstrap_css
endif
# Font Awesome
facss.h: bin2c$(EXEEXT) resources/css/fa.min.css
if HAS_SEDTR
cat resources/css/fa.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/fa.min.css.tmp
./bin2c resources/css/fa.min.css.tmp src/facss.h fa_css
else
./bin2c resources/css/fa.min.css src/facss.h fa_css
endif
# App.css
appcss.h: bin2c$(EXEEXT) resources/css/app.css
if HAS_SEDTR
cat resources/css/app.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/app.css.tmp
./bin2c resources/css/app.css.tmp src/appcss.h app_css
else
./bin2c resources/css/app.css src/appcss.h app_css
endif
# D3.js
d3js.h: bin2c$(EXEEXT) resources/js/d3.v3.min.js
if HAS_SEDTR
cat resources/js/d3.v3.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/d3.v3.min.js.tmp
./bin2c resources/js/d3.v3.min.js.tmp src/d3js.h d3_js
else
./bin2c resources/js/d3.v3.min.js src/d3js.h d3_js
endif
# Hogan.js
hoganjs.h: bin2c$(EXEEXT) resources/js/hogan.min.js
if HAS_SEDTR
cat resources/js/hogan.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/hogan.min.js.tmp
./bin2c resources/js/hogan.min.js.tmp src/hoganjs.h hogan_js
else
./bin2c resources/js/hogan.min.js src/hoganjs.h hogan_js
endif
# Charts.js
chartsjs.h: bin2c$(EXEEXT) resources/js/charts.js
if HAS_SEDTR
cat resources/js/charts.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/charts.js.tmp
./bin2c resources/js/charts.js.tmp src/chartsjs.h charts_js
else
./bin2c resources/js/charts.js src/chartsjs.h charts_js
endif
# App.js
appjs.h: bin2c$(EXEEXT) resources/js/app.js
if HAS_SEDTR
cat resources/js/app.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/app.js.tmp
./bin2c resources/js/app.js.tmp src/appjs.h app_js
else
./bin2c resources/js/app.js src/appjs.h app_js
endif
confdir = $(sysconfdir)/goaccess
dist_conf_DATA = config/goaccess.conf
dist_conf_DATA += config/browsers.list
goaccess_SOURCES = \
src/base64.c \
src/base64.h \
src/browsers.c \
src/browsers.h \
src/color.c \
src/color.h \
src/commons.c \
src/commons.h \
src/csv.c \
src/csv.h \
src/error.c \
src/error.h \
src/gdashboard.c \
src/gdashboard.h \
src/gdns.c \
src/gdns.h \
src/gholder.c \
src/gholder.h \
src/gmenu.c \
src/gmenu.h \
src/goaccess.c \
src/goaccess.h \
src/gslist.c \
src/gslist.h \
src/gstorage.c \
src/gstorage.h \
src/gwsocket.c \
src/gwsocket.h \
src/json.c \
src/json.h \
src/labels.h \
src/opesys.c \
src/opesys.h \
src/options.c \
src/options.h \
src/output.c \
src/output.h \
src/parser.c \
src/parser.h \
src/settings.c \
src/settings.h \
src/sha1.c \
src/sha1.h \
src/sort.c \
src/sort.h \
src/ui.c \
src/ui.h \
src/util.c \
src/util.h \
src/websocket.c \
src/websocket.h \
src/xmalloc.c \
src/xmalloc.h
if TCB
goaccess_SOURCES += \
src/tcabdb.c \
src/tcabdb.h \
src/tcbtdb.c \
src/tcbtdb.h
else
goaccess_SOURCES += \
src/khash.h \
src/gkhash.c \
src/gkhash.h
endif
if GEOIP_LEGACY
goaccess_SOURCES += \
src/geoip1.c \
src/geoip1.h
endif
if GEOIP_MMDB
goaccess_SOURCES += \
src/geoip2.c \
src/geoip1.h
endif
if DEBUG
AM_CFLAGS = -DDEBUG -O0 -g -DSYSCONFDIR=\"$(sysconfdir)\"
else
AM_CFLAGS = -O2 -DSYSCONFDIR=\"$(sysconfdir)\"
endif
if WITH_RDYNAMIC
AM_LDFLAGS = -rdynamic
endif
AM_CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
AM_CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
AM_CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
AM_CFLAGS += -Wbad-function-cast -Winline -Wcast-align -Wextra
AM_CFLAGS += -Wdeclaration-after-statement -Wno-missing-field-initializers
dist_man_MANS = goaccess.1
SUBDIRS = po
ACLOCAL_AMFLAGS = -I m4
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
EXTRA_DIST = config.rpath

File diff suppressed because it is too large Load Diff

@ -1,80 +0,0 @@
Copyright (C) 2009-2018
Gerardo Orellana <goaccess@prosoftcorp.com>
* Version history:
- 1.3 [Friday, November 23, 2018]
. GoAccess 1.3 Released. See ChangeLog for new features/bug-fixes.
- 1.2 [Tuesday, March 07, 2017]
. GoAccess 1.2 Released. See ChangeLog for new features/bug-fixes.
- 1.1.1 [Wednesday, November 23, 2016]
. GoAccess 1.1.1 Released. See ChangeLog for new features/bug-fixes.
- 1.1 [Tuesday, November 08, 2016]
. GoAccess 1.1 Released. See ChangeLog for new features/bug-fixes.
- 1.0.2 [Tuesday, July 05, 2016]
. GoAccess 1.0.2 Released. See ChangeLog for new features/bug-fixes.
- 1.0.1 [Friday, June 17, 2016]
. GoAccess 1.0.1 Released. See ChangeLog for new features/bug-fixes.
- 1.0 [Thursday, June 09, 2016]
. GoAccess 1.0 Released. See ChangeLog for new features/bug-fixes.
- 0.9.8 [Monday, February 29, 2016]
. GoAccess 0.9.8 Released. See ChangeLog for new features/bug-fixes.
- 0.9.7 [Monday, December 21, 2015]
. GoAccess 0.9.7 Released. See ChangeLog for new features/bug-fixes.
- 0.9.6 [Tuesday, October 27, 2015]
. GoAccess 0.9.6 Released. See ChangeLog for new features/bug-fixes.
- 0.9.5 [Thursday, October 22, 2015]
. GoAccess 0.9.5 Released. See ChangeLog for new features/bug-fixes.
- 0.9.4 [Tuesday, September 08 , 2015]
. GoAccess 0.9.4 Released. See ChangeLog for new features/bug-fixes.
- 0.9.3 [Wednesday, August 28, 2015]
. GoAccess 0.9.3 Released. See ChangeLog for new features/bug-fixes.
- 0.9.2 [Monday, July 06, 2015]
. GoAccess 0.9.2 Released. See ChangeLog for new features/bug-fixes.
- 0.9.1 [Tuesday, May 26, 2015]
. GoAccess 0.9.1 Released. See ChangeLog for new features/bug-fixes.
- 0.9 [Thursday, March 19, 2015]
. GoAccess 0.9 Released. See ChangeLog for new features/bug-fixes.
- 0.8.5 [Sunday, September 14, 2014]
. GoAccess 0.8.5 Released. See ChangeLog for new features/bug-fixes.
- 0.8.4 [Monday, September 08, 2014]
. GoAccess 0.8.4 Released. See ChangeLog for new features/bug-fixes.
- 0.8.3 [Monday, July 28, 2014]
. GoAccess 0.8.3 Released. See ChangeLog for new features/bug-fixes.
- 0.8.2 [Monday, July 21, 2014]
. GoAccess 0.8.2 Released. See ChangeLog for new features/bug-fixes.
- 0.8.1 [Monday, June 16, 2014]
. GoAccess 0.8.1 Released. See ChangeLog for new features/bug-fixes.
- 0.8 [Monday, May 20, 2013]
. GoAccess 0.8 Released. See ChangeLog for new features/bug-fixes.
- 0.7.1 [Monday, February 17, 2014]
. GoAccess 0.7.1 Released. See ChangeLog for new features/bug-fixes.
- 0.7 [Monday, December 16, 2013]
. GoAccess 0.7 Released. See ChangeLog for new features/bug-fixes.
- 0.6.1 [Monday, October 07, 2013]
. GoAccess 0.6.1 Released. See ChangeLog for new features/bug-fixes.
- 0.6 [Monday, July 15, 2013]
. GoAccess 0.6 Released. See ChangeLog for new features/bug-fixes.
- 0.5 [Monday, June 04, 2012]
. GoAccess 0.5 Released. See ChangeLog for new features/bug-fixes.
- 0.4.2 [Monday, January 03, 2011]
. GoAccess 0.4.2 Released. See ChangeLog for new features/bug-fixes.
- 0.4.1 [Monday, December 13, 2010]
. GoAccess 0.4.1 Released. See ChangeLog for new features/bug-fixes.
- 0.4 [Tuesday, November 30, 2010]
. GoAccess 0.4 Released. See ChangeLog for new features/bug-fixes.
- 0.3.3 [Monday, September 27, 2010]
. GoAccess 0.3.3 Released. See ChangeLog for new features/bug-fixes.
- 0.3.2 [Thursday, September 09 2010]
. GoAccess 0.3.2 Released. See ChangeLog for new features/bug-fixes.
- 0.3.1 [Friday, September 03, 2010]
. GoAccess 0.3.1 Released. See ChangeLog for new features/bug-fixes.
- 0.3 [Sunday, August 29, 2010]
. GoAccess 0.3 Released. See ChangeLog for new features/bug-fixes.
- 0.2 [Sunday, July 25, 2010]
. GoAccess 0.2 Released. See ChangeLog for new features/bug-fixes.
- 0.1.2 [Tuesday, July 13, 2010]
. GoAccess 0.1.2 Released. See ChangeLog for new features/bug-fixes.
- 0.1.1 [Saturday, July 10, 2010]
. GoAccess 0.1.1 Released. See ChangeLog for new features/bug-fixes.
- 0.1 [Wednesday, July 07, 2010]
. Welcome to the GoAccess 0.1 Released.

@ -1,100 +0,0 @@
What is it?
-------------
GoAccess is an open source real-time web log analyzer and interactive viewer
that runs in a terminal in *nix systems or through your browser.
It provides fast and valuable HTTP statistics for system administrators that
require a visual server report on the fly.
Features
-------------------------------
GoAccess parses the specified web log file and
outputs the data to the X terminal. Features include:
* Completely Real Time
All panels and metrics are timed to be updated every 200 ms on the terminal
output and every second on the HTML output.
* No configuration needed
You can just run it against your access log file, pick the log format and
let GoAccess parse the access log and show you the stats.
* Track Application Response Time
Track the time taken to serve the request. Extremely useful if you want to
track pages that are slowing down your site.
* Nearly All Web Log Formats
GoAccess allows any custom log format string. Predefined options include,
Apache, Nginx, Amazon S3, Elastic Load Balancing, CloudFront, etc
* Incremental Log Processing
Need data persistence? GoAccess has the ability to process logs incrementally
through the on-disk B+Tree database.
* Only one dependency
GoAccess is written in C. To run it, you only need ncurses as a dependency.
That's it. It even has its own Web Socket server - http://gwsocket.io/.
* Visitors
Determine the amount of hits, visitors, bandwidth, and metrics for slowest
running requests by the hour, or date.
* Metrics per Virtual Host
Have multiple Virtual Hosts (Server Blocks)? A panel that displays which
virtual host is consuming most of the web server resources.
* Color Scheme Customizable
Tailor GoAccess to suit your own color taste/schemes. Either through the
terminal, or by simply updating the stylesheet on the HTML output.
* Support for large datasets
GoAccess features an on-disk B+Tree storage for large datasets where it is not
possible to fit everything in memory.
* Docker support
GoAccess comes with a default Docker (https://hub.docker.com/r/allinurl/goaccess/)
that will listen for HTTP connections on port 7890. Although, you can still
fully configure it, by using Volume mapping and editing goaccess.conf.
* and more... visit https://goaccess.io for more details.
Why GoAccess?
-------------
GoAccess was designed to be a fast, terminal-based log analyzer. Its core idea
is to quickly analyze and view web server statistics in real time without
needing to use your browser (great if you want to do a quick analysis of your
access log via SSH, or if you simply love working in the terminal).
While the terminal output is the default output, it has the capability to
generate a complete real-time HTML report, as well as a JSON, and CSV report.
You can see it more of a monitor command tool than anything else.
Keys
----
The user can make use of the following keys:
* ^F1^ or ^h^ Main help,
* ^F5^ Redraw [main window],
* ^q^ Quit the program, current window or module,
* ^o^ or ^ENTER^ Expand selected module,
* ^[Shift]0-9^ Set selected module to active,
* ^Up^ arrow Scroll up main dashboard,
* ^Down^ arrow Scroll down main dashboard,
* ^j^ Scroll down within expanded module,
* ^k^ Scroll up within expanded module,
* ^c^ Set or change scheme color,
* ^CTRL^ + ^f^ Scroll forward one screen within,
* active module,
* ^CTRL^ + ^b^ Scroll backward one screen within,
* active module,
* ^TAB^ Iterate modules (forward),
* ^SHIFT^ + ^TAB^ Iterate modules (backward),
* ^s^ Sort options for current module,
* ^/^ Search across all modules,
* ^n^ Find position of the next occurrence,
* ^g^ Move to the first item or top of screen,
* ^G^ Move to the last item or bottom of screen,
Examples can be found by running `man goaccess`.

@ -1,10 +0,0 @@
1Copyright (C) 2009-2018
6erardo Orellana <goaccess@prosoftcorp.com>
For a more comprehensive list of to-do items, please refer to the GitHub site.
https://github.com/allinurl/goaccess/issues
or visit http://goaccess.io/faq#todo
If you are interested in working on any of the items listed in there, email
goaccess@prosoftcorp.com or better, open a new issue:

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -1,343 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-03-05.13; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
# Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,672 +0,0 @@
#! /bin/sh
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2010 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's _LT_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
darwin*)
case $cc_basename in
xlc*)
wl='-Wl,'
;;
esac
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
newsos6)
;;
linux* | k*bsd*-gnu)
case $cc_basename in
ecc*)
wl='-Wl,'
;;
icc* | ifort*)
wl='-Wl,'
;;
lf95*)
wl='-Wl,'
;;
pgcc | pgf77 | pgf90)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
wl='-Wl,'
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
# that the semantics of dynamic libraries on AmigaOS, at least up
# to version 4, is to share data among multiple programs linked
# with the same dynamic library. Since this doesn't match the
# behavior of shared libraries on other platforms, we cannot use
# them.
ld_shlibs=no
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32* | cegcc*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | k*bsd*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix[4-9]*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# see comment about different semantics on the GNU ld section
ld_shlibs=no
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if test "$GCC" = yes ; then
:
else
case $cc_basename in
xlc*)
;;
*)
ld_shlibs=no
;;
esac
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd1*)
ld_shlibs=no
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix[4-9]*)
library_names_spec='$libname$shrext'
;;
amigaos*)
library_names_spec='$libname.a'
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32* | cegcc*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd1*)
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
nto-qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,102 +0,0 @@
# List of browsers and their categories
# e.g., WORD delimited by tab(s) TYPE
#
# **IMPORTANT NOTE**:
# ---------------------
# The SIZE of the list is proportional to the run time.
# Thus, the longer the list, the more time GoAccess will take to parse it.
#
# Also, you should note that the higher the browser/item is on the list, the
# faster the parsing will be.
#
# The list needs to be specified using --browsers-file=<path>. This file is not
# parsed by default.
#
# The items below are sample crawlers, adjust as needed.
Chef Client Crawlers
Abonti Crawlers
SISTRIX Crawlers
DotBot Crawlers
Speedy Spider Crawlers
Sosospider Crawlers
BPImageWalker Crawlers
DoCoMo Crawlers
GSLFbot Crawlers
YodaoBot Crawlers
AddThis Crawlers
Purebot Crawlers
CCBot Crawlers
findlinks Crawlers
ichiro Crawlers
Linguee Bot Crawlers
Gigabot Crawlers
BacklinkCrawler Crawlers
distilator Crawlers
Aboundex Crawlers
UnwindFetchor Crawlers
SBIder Crawlers
TestNutch Crawlers
DomainCrawler Crawlers
NextGenSearchBot Crawlers
SEOENGWorldBot Crawlers
Cityreview Crawlers
PagePeeker Crawlers
JS-Kit Crawlers
ScreenerBot Crawlers
ShowyouBot Crawlers
SolomonoBot Crawlers
Domnutch Crawlers
MaxPoint Crawlers
NCBot Crawlers
TosCrawler Crawlers
Updownerbot Crawlers
OpenWebSpider Crawlers
WordPress Crawlers
PEAR Crawlers
ZumBot Crawlers
YisouSpider Crawlers
W3C Crawlers
vcheck Crawlers
PercolateCrawler Crawlers
NING Crawlers
gvfs Crawlers
CatchBot Crawlers
Combine Crawlers
A6-Indexer Crawlers
Altresium Crawlers
Comodo Crawlers
crawler4j Crawlers
Cricket Crawlers
EC2LinkFinder Crawlers
envolk Crawlers
GeoHasher Crawlers
HTMLParser Crawlers
MLBot Crawlers
Jaxified Crawlers
LinkWalker Crawlers
nutch Crawlers
PostRank Crawlers
keybase-proofs Crawlers
CommonCrawler Crawlers
X-CAD-SE Crawlers
Safeassign Crawlers
Nmap Crawlers
sqlmap Crawlers
Jorgee Crawlers
PxBroker Crawlers
Seekport Crawlers
adscanner Crawlers
AfD-Verbotsverfahren_JETZT! Crawlers
Vienna Feeds
Windows-RSS-Platform Feeds
newsbeuter Feeds
Wrangler Feeds
Fever Feeds
Tiny Feeds
FreshRSS Feeds
KrISS Feeds
SimplePie Feeds
Feedsubs Feeds
UniversalFeedParser Feeds

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save