LogParser

Given a txt document consisting of log information, find time as a percentage - spent connected.

  • The time started is the first line, and the time ended is the last line.

  • Information inbetween consists of various information, but what we are interested in the total amount of time connected vs time total amount of time disconnected.

Examples

(11/01/2015-04:00:00) :: START
(11/01/2015-04:00:00) :: CONNECTED
(11/01/2015-04:30:00) :: DISCONNECTED
(11/01/2015-04:45:00) :: CONNECTED
(11/01/2015-05:00:00) :: SHUTDOWN

output: 75%
(11/01/2015-03:30:00) :: START
(11/01/2015-03:30:00) :: CONNECTED
(11/01/2015-04:00:00) :: DISCONNECTED
(11/01/2015-04:15:00) :: SHUTDOWN

output: 66%
(01/01/2015-00:00:00) :: START
(01/01/2015-00:00:05) :: CONNECTED
(01/01/2015-00:01:23) :: UI - HUD animation state changed
(01/01/2015-00:03:47) :: ERROR - Unknown error
(01/01/2015-00:12:11) :: DISCONNECTED
(01/01/2015-00:13:14) :: UI - HUD animation state changed
(01/01/2015-00:13:50) :: CONNECTED
(01/01/2015-00:17:20) :: UI - HUD animation state changed
(01/01/2015-00:21:06) :: Crash report sent to server successfully
(01/01/2015-00:22:00) :: Warning: please implement this
(01/01/2015-00:23:50) :: Warning: please implement this
(01/01/2015-00:28:41) :: DISCONNECTED
(01/01/2015-00:31:31) :: UI - HUD animation state changed
(01/01/2015-00:32:12) :: ERROR - Unknown error
(01/01/2015-00:35:45) :: CONNECTED
(01/01/2015-00:36:50) :: DISCONNECTED
(01/01/2015-00:37:01) :: Warning: please implement this
(01/01/2015-00:38:22) :: Crash report sent to server unsuccessfully
(01/01/2015-00:38:23) :: ERROR - Unknown error
(01/01/2015-00:39:17) :: CONNECTED
(01/01/2015-00:40:40) :: UI - HUD animation state changed
(01/01/2015-00:40:42) :: UI - HUD animation state changed
(01/01/2015-00:42:15) :: Crash report sent to server successfully
(01/01/2015-00:42:30) :: DISCONNECTED
(01/01/2015-00:43:56) :: UI - HUD animation state changed
(01/01/2015-00:44:18) :: CONNECTED
(01/01/2015-01:00:00) :: SHUTDOWN

78%
class LogParser {
public:
    static std::string parseFile(const std::string&);
    static std::string parseLines(const std::vector < std::string >& lines);
};

class Time {
public:
    Time(string time) {
        parse(time);
    }

    Time(int short h, int short m, int short s) {
        hr = h; min = m; sec = s;
    }

    Time() { hr = min = sec = 0; }

    friend Time operator-(const Time &one, const Time &two);

    void operator +=(const Time& rhs) {
        hr  = rhs.hr + hr;
        min = rhs.min + min;
        sec = rhs.sec + sec;
    }

    void operator=(const Time &rhs) {
        hr  = rhs.hr;
        min = rhs.min;
        sec = rhs.sec;
    }

    // this function also takes care of 
    // negatives e.g. 01:-15:00
    float convert_to_min() {
        float hr_min = hr * 60;
        float sec_min = sec / 60;
        return hr_min + min + sec_min;
    }

    int short hr, min, sec;

private:
    void parse(string &time) {
        hr  =  atoi(time.substr(0, 2).c_str());
        min =  atoi(time.substr(3, 5).c_str());
        sec =  atoi(time.substr(6, 8).c_str());
    }
};

float get_ratio(Time & t1, Time & t2)
{
    return t1.convert_to_min() / t2.convert_to_min();
}

Time operator-(const Time &one, const Time &two) {
    int h, m, s;
    h = one.hr - two.hr;
    m = one.min - two.min;
    s = one.sec - two.sec;

    return Time(h, m, s);
}


std::string LogParser::parseFile(const std::string& filename) {
    std::ifstream ifs(filename.c_str(), std::ios::in);
    if (!ifs) { throw "File not found!"; }

    std::vector < std::string > lines;
    std::string line;
    while (std::getline(ifs, line)) {
        lines.push_back(line);
    };

    return LogParser::parseLines(lines);
}

std::string LogParser::parseLines(const std::vector <std::string>& lines) {
    // get the start and end time
    Time very_start(lines.at(0).substr(12, 8));
    Time very_end(lines.at(lines.size() - 1).substr(12, 8));

    Time length = very_start - very_end;

    bool is_disconnect = false;
    bool is_connected = false;

    Time sum_disconnect;
    Time start, end;

    // ignore first 2 lines
    for (int i = 2; i < lines.size(); i++) {
        string cur_str = lines.at(i);
        string sub_str_status = cur_str.substr(25, cur_str.length() - 1);
        string cur_time = cur_str.substr(12, 8);
        if (sub_str_status == "CONNECTED" || sub_str_status == "SHUTDOWN") {
            is_connected = true;
            end = Time(cur_time);
        }
        else if (sub_str_status == "DISCONNECTED" ){
            is_disconnect = true;
            start = Time(cur_time);
        }

        if (is_disconnect && is_connected) {
            sum_disconnect += start - end;
            is_disconnect = is_connected = false;
        }
    }

    Time diff = length - sum_disconnect;
    string final_str = to_string(get_ratio(diff, length));
    return final_str.substr(2,2) + "%";
}

int main(int argc, char** argv)
{
    LogParser p;
    cout << p.parseFile(argv[1]) << endl;
}

Last updated