xitiomet is sharing code with you

Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.

Don't show this again

xitiomet / nglog

Simple Command line utility for parsing nginx logs into csv files.

Clone this repository (size: 44.2 KB): HTTPS / SSH
hg clone https://bitbucket.org/xitiomet/nglog
hg clone ssh://hg@bitbucket.org/xitiomet/nglog

nglog / nglog.cc

commit
a624f6dc89d9
parent
835500c42a0e
branch
default

Fixed warnings with unsigned ints

1
ee2b834af766
#include <iostream>
2
ee2b834af766
#include <sstream>
3
ee2b834af766
#include <fstream>
4
ee2b834af766
#include <vector>
5
ee2b834af766
#include <string>
6
ee2b834af766
#include "vt100.h"
7
ee2b834af766
8
ee2b834af766
using namespace std;
9
ee2b834af766
10
ee2b834af766
struct Param
11
ee2b834af766
{
12
ee2b834af766
    string key;
13
ee2b834af766
    string value;
14
ee2b834af766
};
15
ee2b834af766
16
ee2b834af766
struct Request
17
ee2b834af766
{
18
ee2b834af766
    string url;
19
835500c42a0e
    string timestamp;
20
ee2b834af766
    vector<Param> params;
21
ee2b834af766
};
22
ee2b834af766
23
ee2b834af766
struct PreparedLog
24
ee2b834af766
{
25
ee2b834af766
    vector<Request> requests;
26
ee2b834af766
    vector<string> columns;
27
ee2b834af766
    float total_lines;
28
ee2b834af766
};
29
ee2b834af766
30
ee2b834af766
void unique_add(vector<string>& v, string& s)
31
ee2b834af766
{
32
a624f6dc89d9
    unsigned int i;
33
ee2b834af766
    bool found = false;
34
ee2b834af766
    for (i=0; i < v.size(); i++)
35
ee2b834af766
    {
36
ee2b834af766
        if (v.at(i) == s)
37
ee2b834af766
        {
38
ee2b834af766
            found = true;
39
ee2b834af766
        }
40
ee2b834af766
    }
41
ee2b834af766
    if (!found)
42
ee2b834af766
    {
43
ee2b834af766
        v.push_back(s);
44
ee2b834af766
    }
45
ee2b834af766
}
46
ee2b834af766
47
ee2b834af766
string get_param(vector<Param> v, string key)
48
ee2b834af766
{
49
a624f6dc89d9
    unsigned int i;
50
ee2b834af766
    for (i=0; i < v.size(); i++)
51
ee2b834af766
    {
52
ee2b834af766
        Param e = v.at(i);
53
ee2b834af766
        if (key == e.key)
54
ee2b834af766
        {
55
ee2b834af766
            return e.value;
56
ee2b834af766
        }
57
ee2b834af766
    }
58
ee2b834af766
    return "";
59
ee2b834af766
}
60
ee2b834af766
61
ee2b834af766
PreparedLog prepareLog(istream& input_stream)
62
ee2b834af766
{
63
ee2b834af766
    string line;
64
a624f6dc89d9
    unsigned int linenum = 0;
65
ee2b834af766
    PreparedLog return_log;
66
ee2b834af766
    while (getline (input_stream, line))
67
ee2b834af766
    {
68
ee2b834af766
        linenum++;
69
835500c42a0e
	// unique struct for line
70
835500c42a0e
        Request this_request;
71
ee2b834af766
        istringstream linestream(line);
72
ee2b834af766
        string item;
73
ee2b834af766
        int itemnum = 0;
74
ee2b834af766
        while (getline (linestream, item, ' '))
75
ee2b834af766
        {
76
ee2b834af766
            itemnum++;
77
835500c42a0e
	    if (itemnum == 4)
78
835500c42a0e
	    {
79
835500c42a0e
	       this_request.timestamp = item.substr(1);
80
835500c42a0e
	    } 
81
ee2b834af766
            if (itemnum == 7)
82
ee2b834af766
            {
83
ee2b834af766
                int qloc = item.find_first_of("?");
84
ee2b834af766
                string url_params;
85
ee2b834af766
                string url;
86
ee2b834af766
87
ee2b834af766
                if (qloc != string::npos)
88
ee2b834af766
                {
89
ee2b834af766
                    this_request.url = item.substr(0, qloc);
90
ee2b834af766
                    url_params = item.substr(qloc+1);
91
ee2b834af766
92
ee2b834af766
                    int paramnumber = 0;
93
ee2b834af766
                    istringstream paramstream(url_params);
94
ee2b834af766
                    string param;
95
ee2b834af766
96
ee2b834af766
                    // Check parameters to see what kind of colums we will have to create
97
ee2b834af766
                    while (getline (paramstream, param, '&'))
98
ee2b834af766
                    {
99
ee2b834af766
                        int eqloc = param.find_first_of("=");
100
ee2b834af766
                        if (eqloc != string::npos)
101
ee2b834af766
                        {
102
ee2b834af766
                            Param x;
103
ee2b834af766
104
ee2b834af766
                            x.key = param.substr(0,eqloc);
105
ee2b834af766
                            x.value = param.substr(eqloc+1);
106
ee2b834af766
107
ee2b834af766
                            this_request.params.push_back(x);
108
ee2b834af766
109
ee2b834af766
                            // if not in column db add it
110
ee2b834af766
                            unique_add(return_log.columns, x.key);
111
ee2b834af766
                        }
112
ee2b834af766
                    }
113
ee2b834af766
114
ee2b834af766
                } else {
115
ee2b834af766
                    // No Parameters lets just get the url
116
ee2b834af766
                    this_request.url = item;
117
ee2b834af766
                }
118
ee2b834af766
                return_log.requests.push_back(this_request);
119
ee2b834af766
            }
120
ee2b834af766
        }
121
ee2b834af766
    }
122
ee2b834af766
    return_log.total_lines = linenum;
123
ee2b834af766
    return return_log;
124
ee2b834af766
}
125
ee2b834af766
126
ee2b834af766
void write_csv(PreparedLog& plog, ostream& outfile)
127
ee2b834af766
{
128
835500c42a0e
    outfile << "\"timestamp\",\"url\",";
129
a624f6dc89d9
    unsigned int c;
130
ee2b834af766
    for (c=0; c < plog.columns.size(); c++)
131
ee2b834af766
    {
132
ee2b834af766
        string f = plog.columns.at(c);
133
ee2b834af766
        outfile << "\"" << f << "\"";
134
ee2b834af766
        if (c+1 < plog.columns.size())
135
ee2b834af766
        {
136
ee2b834af766
            outfile << ",";
137
ee2b834af766
        }
138
ee2b834af766
    }
139
ee2b834af766
    outfile << endl;
140
ee2b834af766
141
a624f6dc89d9
    unsigned int i;
142
ee2b834af766
    for (i=0; i < plog.requests.size(); i++)
143
ee2b834af766
    {
144
ee2b834af766
        Request n = plog.requests.at(i);
145
835500c42a0e
        outfile << "\"" << n.timestamp << "\"," << "\"" << n.url << "\",";
146
a624f6dc89d9
        unsigned int b;
147
ee2b834af766
        for (b=0; b < plog.columns.size(); b++)
148
ee2b834af766
        {
149
ee2b834af766
            string e = plog.columns.at(b);
150
ee2b834af766
            outfile << "\"" << get_param(n.params, e) << "\"";
151
ee2b834af766
            if (b+1 < plog.columns.size())
152
ee2b834af766
            {
153
ee2b834af766
                outfile << ",";
154
ee2b834af766
            }
155
ee2b834af766
        }
156
ee2b834af766
        outfile << endl;
157
ee2b834af766
    }
158
ee2b834af766
}
159
ee2b834af766
160
ee2b834af766
string view_vector(vector<string>& v)
161
ee2b834af766
{
162
a624f6dc89d9
    unsigned int i;
163
ee2b834af766
    ostringstream oss;
164
ee2b834af766
    for (i=0; i < v.size(); i++)
165
ee2b834af766
    {
166
ee2b834af766
        oss << v.at(i);
167
ee2b834af766
        if (i+1 < v.size())
168
ee2b834af766
        {
169
ee2b834af766
            oss << ", ";
170
ee2b834af766
        }
171
ee2b834af766
    }
172
ee2b834af766
    return oss.str();
173
ee2b834af766
}
174
ee2b834af766
175
ee2b834af766
176
ee2b834af766
int main (int argc, char *argv[])
177
ee2b834af766
{
178
ee2b834af766
    int i;
179
cb79cc5c5175
    bool std_in = false;
180
cb79cc5c5175
    bool std_out = false;
181
ee2b834af766
    bool show_help = true;
182
ee2b834af766
    bool input_set = false;
183
ee2b834af766
    bool output_set = false;
184
ee2b834af766
    bool quiet = false;
185
ee2b834af766
    
186
ee2b834af766
    string outFilename;
187
ee2b834af766
    string inFilename;
188
ee2b834af766
    
189
ee2b834af766
    for (i=0; i<argc; i++)
190
ee2b834af766
    {
191
ee2b834af766
        string thisParam = argv[i];
192
ee2b834af766
        if (!thisParam.compare("--help"))
193
ee2b834af766
        {
194
ee2b834af766
            show_help = true;
195
ee2b834af766
        }
196
ee2b834af766
        
197
ee2b834af766
        if (!thisParam.compare("--pipe"))
198
ee2b834af766
        {
199
cb79cc5c5175
            std_in = true;
200
ee2b834af766
            inFilename = "";
201
cb79cc5c5175
            std_out = true;
202
ee2b834af766
            inFilename = "";
203
ee2b834af766
            
204
ee2b834af766
            input_set = true;
205
ee2b834af766
            output_set = true;
206
ee2b834af766
        }
207
ee2b834af766
        
208
ee2b834af766
        if (!thisParam.compare("--quiet"))
209
ee2b834af766
        {
210
ee2b834af766
            quiet = true;
211
ee2b834af766
        }
212
ee2b834af766
        
213
ee2b834af766
        if (!thisParam.compare("--stdin"))
214
ee2b834af766
        {
215
cb79cc5c5175
            std_in = true;
216
ee2b834af766
            inFilename = "";
217
ee2b834af766
            
218
ee2b834af766
            input_set = true;
219
ee2b834af766
        }
220
ee2b834af766
        
221
ee2b834af766
        if (!thisParam.compare("--stdout"))
222
ee2b834af766
        {
223
cb79cc5c5175
            std_out = true;
224
ee2b834af766
            outFilename = "";
225
ee2b834af766
            
226
ee2b834af766
            output_set = true;
227
ee2b834af766
        }
228
ee2b834af766
229
ee2b834af766
        if (!thisParam.compare("-o"))
230
ee2b834af766
        {
231
ee2b834af766
            outFilename = argv[i+1];
232
cb79cc5c5175
            std_out = false;
233
ee2b834af766
            
234
ee2b834af766
            output_set = true;
235
ee2b834af766
        }
236
ee2b834af766
237
ee2b834af766
        if (!thisParam.compare("-i"))
238
ee2b834af766
        {
239
ee2b834af766
            inFilename = argv[i+1];
240
cb79cc5c5175
            std_in = false;
241
ee2b834af766
            
242
ee2b834af766
            input_set = true;
243
ee2b834af766
        }
244
ee2b834af766
    }
245
ee2b834af766
    
246
ee2b834af766
    if (input_set && output_set)
247
ee2b834af766
    {
248
ee2b834af766
        show_help = false;
249
ee2b834af766
    }
250
ee2b834af766
    
251
ee2b834af766
    if (show_help)
252
ee2b834af766
    {
253
ee2b834af766
        cerr << "Usage: nglog [OPTION] -i [FILE] -o [FILE]" << endl;
254
ee2b834af766
        cerr << "Process nginx logs for urls into csv files. Used to debug restfull api calls through nginx" << endl;
255
ee2b834af766
        cerr << endl;
256
ee2b834af766
        cerr << "Options:" << endl;
257
ee2b834af766
        cerr << "  --pipe           Take input from stdin, and send output to stdout" << endl;
258
ee2b834af766
        cerr << "  --stdin          Take input from stdin" << endl;
259
ee2b834af766
        cerr << "  --stdout         Send output to stdout" << endl;
260
ee2b834af766
        cerr << "  --quiet          No Messages" << endl;
261
ee2b834af766
        cerr << "  -i               Specify Input file (NGINX LOG)" << endl;
262
ee2b834af766
        cerr << "  -o               Specify Output file (CSV)" << endl << endl;
263
ee2b834af766
        return 0;
264
ee2b834af766
    }
265
ee2b834af766
    
266
ee2b834af766
    if (!quiet)
267
ee2b834af766
    {
268
ee2b834af766
        cerr << set_bold(true) << set_colors(VT_RED, VT_DEFAULT) << "NGINX Weblog Parser" << set_bold(false) << endl;
269
ee2b834af766
        cerr << set_colors(VT_YELLOW, VT_DEFAULT)<< "Processing " << inFilename << "....";
270
ee2b834af766
    }
271
ee2b834af766
272
ee2b834af766
    istream *input_stream;
273
ee2b834af766
    ifstream inFile;
274
cb79cc5c5175
    if (!std_in)
275
ee2b834af766
    {    
276
ee2b834af766
        inFile.open(inFilename.c_str());
277
ee2b834af766
        input_stream = &inFile;
278
ee2b834af766
    } else {
279
ee2b834af766
        input_stream = &cin;
280
ee2b834af766
    }
281
ee2b834af766
    PreparedLog plog = prepareLog(*input_stream);
282
ee2b834af766
283
ee2b834af766
    if (!quiet)
284
ee2b834af766
    {
285
ee2b834af766
        cerr << set_colors(VT_DEFAULT, VT_DEFAULT) << "OK!" << set_colors(VT_DEFAULT, VT_DEFAULT) << endl;
286
ee2b834af766
        cerr << set_colors(VT_YELLOW, VT_DEFAULT) << "Lines Processed: " << set_colors(VT_DEFAULT, VT_DEFAULT) << plog.total_lines << endl;
287
ee2b834af766
        cerr << set_colors(VT_YELLOW, VT_DEFAULT) << "Columns Detected: " << set_colors(VT_DEFAULT, VT_DEFAULT) << view_vector(plog.columns) << endl;
288
ee2b834af766
        cerr << finalize;
289
ee2b834af766
    }
290
ee2b834af766
    
291
cb79cc5c5175
    if (!std_out)
292
ee2b834af766
    {
293
ee2b834af766
        ofstream outfile (outFilename.c_str());
294
ee2b834af766
        write_csv(plog, outfile);
295
ee2b834af766
        outfile.close();
296
ee2b834af766
    } else {
297
ee2b834af766
        write_csv(plog, cout);
298
ee2b834af766
    }
299
ee2b834af766
    return 0;
300
ee2b834af766
}
301
ee2b834af766