Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <algorithm>
- #include <iterator>
- #include <thread>
- #include <unistd.h>
- #include <vector>
- #include <string>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <mutex>
- #include <chrono>
- #include <iomanip>
- #include <functional>
- #define SOCK_PATH "/home/threads_loger"
- #define BUF_LEN 256
- time_t parse_time(std::string str) {
- tm ret;
- memset(&ret, 0, sizeof(tm));
- strptime(str.c_str(), "%F %T", &ret);
- return mktime(&ret);
- }
- void connection_thread(int sock, struct sockaddr_un addr, std::fstream &log,
- std::mutex &log_mutex) {
- auto sender = [sock](std::string tmp, int end = 1) -> int {
- tmp.resize(BUF_LEN);
- tmp[BUF_LEN - 1] = end;
- if (send(sock, tmp.c_str(), BUF_LEN, 0) < 0) {
- perror("send");
- return 0;
- }
- return 1;
- };
- auto get_time =
- []() -> std::string {
- std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
- char tmp[50];
- strftime(tmp, 50UL, "%F %T", localtime(&now));
- return std::string {tmp};
- };
- auto file_find =
- [&log, &log_mutex, &sender](std::function<bool(std::string&)> cond) {
- std::lock_guard<std::mutex> lg {log_mutex};
- log.close();
- log.open("log.txt", std::fstream::in);
- log.seekg(0);
- std::string line;
- while(std::getline(log, line)) {
- if(cond(line)) {
- sender(line, 0);
- }
- }
- log.close();
- log.open("log.txt", std::fstream::in | std::fstream::out | std::fstream::app);
- };
- while (1) {
- char buffer[256];
- int n, total = 0;
- while (total != 256) {
- n = recv(sock, buffer + total, 256, MSG_WAITALL);
- if (n < 0) {
- perror("recv");
- } else if (n == 0) {
- break;
- }
- total += n;
- }
- if (n == 0) {
- break;
- }
- //get level *, get from * to *, get from *, clear, write * *
- std::istringstream iss { std::string(buffer) };
- std::string cmd;
- iss >> cmd;
- if (cmd == "write") {
- std::string level, message, time;
- iss >> level;
- time = get_time();
- if (level == "warn" || level == "info" || level == "error") {
- char c;
- while (isspace(c = iss.get()))
- ;
- iss.putback(c);
- std::getline(iss, message);
- std::lock_guard<std::mutex> lg { log_mutex };
- log << level << " " << time << " " << message << std::endl;
- } else {
- if (!sender("wrong type"))
- break;
- continue;
- }
- } else if (cmd == "get") {
- std::vector<std::string> tokens {
- std::istream_iterator<std::string> { iss },
- std::istream_iterator<std::string> { } };
- if (tokens.size() == 0) {
- if (!sender("no args"))
- break;
- continue;
- } else if (tokens[0] == "level") {
- if(tokens[1] == "warn" || tokens[1] == "error" || tokens[1] == "info") {
- file_find([&level = tokens[1]](std::string &line) -> bool {
- if(strncmp(line.c_str(), level.c_str(), strlen(level.c_str())) == 0)
- return true;
- return false;
- });
- } else {
- if(!sender("wrong type"))
- break;
- continue;
- }
- } else if (tokens[0] == "from" && tokens.size() == 3) {
- file_find([&tokens, from = parse_time(tokens[1] + tokens[2])](std::string &line)-> bool {
- std::istringstream iss {line};
- std::string tmp1, tmp2;
- iss >> tmp1 >> tmp1 >> tmp2;
- if(parse_time(tmp1 + tmp2) >= from)
- return true;
- return false;
- });
- } else if (tokens[0] == "from" && tokens.size() == 6 && tokens[3] == "to") {
- file_find([&tokens, from = parse_time(tokens[1] + tokens[2]), to = parse_time(tokens[4] + tokens[5])](std::string &line)-> bool {
- std::istringstream iss {line};
- std::string tmp1, tmp2;
- iss >> tmp1 >> tmp1 >> tmp2;
- if(parse_time(tmp1 + tmp2) >= from && parse_time(tmp1 + tmp2) <= to)
- return true;
- return false;
- });
- } else {
- if (!sender("wrong syntax"))
- break;
- continue;
- }
- } else if (cmd == "clear") {
- std::lock_guard<std::mutex> lg { log_mutex };
- log.close();
- log.open("log.txt",
- std::fstream::in | std::fstream::out | std::fstream::trunc);
- } else {
- if (!sender("wrong command"))
- break;
- continue;
- }
- if(!sender("ok!"))
- break;
- }
- close(sock);
- unlink(addr.sun_path);
- log.sync();
- }
- int main() {
- int server_sock, client_sock, client_len, len;
- struct sockaddr_un server, client;
- std::fstream fout;
- fout.open("log.txt",
- std::fstream::in | std::fstream::out | std::ios_base::app);
- if ((server_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- perror("socket");
- }
- server.sun_family = AF_UNIX;
- strcpy(server.sun_path, SOCK_PATH);
- unlink(server.sun_path);
- len = strlen(server.sun_path) + sizeof(server.sun_family);
- if (bind(server_sock, (struct sockaddr *) &server, len) < 0) {
- perror("bind");
- }
- if (listen(server_sock, 5) < 0) {
- perror("listen");
- }
- std::mutex log_mutex;
- for (;;) {
- printf("Waiting for a connection...\n");
- client_len = sizeof(client);
- if ((client_sock = accept(server_sock, (struct sockaddr *) &client,
- (socklen_t *) &client_len)) < 0) {
- perror("accept");
- }
- printf("Connected.\n");
- std::thread(connection_thread, client_sock, server, std::ref(fout),
- std::ref(log_mutex)).detach();
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement