varnish-cache/bin/varnishlog/varnishlog.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 * Author: Martin Blix Grydeland <martin@varnish-software.com>
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 * Log tailer for Varnish
31
 */
32
33
#include "config.h"
34
35
#include <stdarg.h>
36
#include <stdlib.h>
37
#include <stdio.h>
38
#include <unistd.h>
39
#include <string.h>
40
#include <errno.h>
41
#include <stdint.h>
42
43
#define VOPT_DEFINITION
44
#define VOPT_INC "varnishlog_options.h"
45
46
#include "vdef.h"
47
48
#include "vapi/vsm.h"
49
#include "vapi/vsl.h"
50
#include "vapi/voptget.h"
51
#include "vas.h"
52
#include "vut.h"
53
#include "miniobj.h"
54
55
static struct VUT *vut;
56
57
static struct log {
58
        /* Options */
59
        int             a_opt;
60
        int             A_opt;
61
        char            *w_arg;
62
63
        /* State */
64
        FILE            *fo;
65
} LOG;
66
67
static void v_noreturn_
68 8
usage(int status)
69
{
70
        const char **opt;
71 8
        fprintf(stderr, "Usage: %s <options>\n\n", vut->progname);
72 8
        fprintf(stderr, "Options:\n");
73 200
        for (opt = vopt_spec.vopt_usage; *opt != NULL; opt += 2)
74 192
                fprintf(stderr, " %-25s %s\n", *opt, *(opt + 1));
75 8
        exit(status);
76
}
77
78
static void
79 20
openout(int append)
80
{
81
82 20
        AN(LOG.w_arg);
83 20
        if (LOG.A_opt)
84 8
                LOG.fo = fopen(LOG.w_arg, append ? "a" : "w");
85
        else
86 12
                LOG.fo = VSL_WriteOpen(vut->vsl, LOG.w_arg, append, 0);
87 20
        if (LOG.fo == NULL)
88 8
                VUT_Error(vut, 2, "Cannot open output file (%s)",
89 8
                    LOG.A_opt ? strerror(errno) : VSL_Error(vut->vsl));
90 16
        vut->dispatch_priv = LOG.fo;
91 16
}
92
93
static int v_matchproto_(VUT_cb_f)
94 4
rotateout(struct VUT *v)
95
{
96
97 4
        assert(v == vut);
98 4
        AN(LOG.w_arg);
99 4
        AN(LOG.fo);
100 4
        fclose(LOG.fo);
101 4
        openout(1);
102 4
        AN(LOG.fo);
103 4
        return (0);
104
}
105
106
static int v_matchproto_(VUT_cb_f)
107 6241
flushout(struct VUT *v)
108
{
109
110 6241
        assert(v == vut);
111 6241
        AN(LOG.fo);
112 6241
        if (fflush(LOG.fo))
113 0
                return (-5);
114 6241
        return (0);
115
}
116
117
static int v_matchproto_(VUT_cb_f)
118 0
sighup(struct VUT *v)
119
{
120 0
        assert(v == vut);
121 0
        return (1);
122
}
123
124
static void
125 12
vut_sighandler(int sig)
126
{
127
128 12
        if (vut != NULL)
129 12
                VUT_Signaled(vut, sig);
130 12
}
131
132
int
133 164
main(int argc, char * const *argv)
134
{
135
        int opt;
136
137 164
        vut = VUT_InitProg(argc, argv, &vopt_spec);
138 156
        AN(vut);
139 156
        memset(&LOG, 0, sizeof LOG);
140
141 588
        while ((opt = getopt(argc, argv, vopt_spec.vopt_optstring)) != -1) {
142 332
                switch (opt) {
143
                case 'a':
144
                        /* Append to file */
145 0
                        LOG.a_opt = 1;
146 0
                        break;
147
                case 'A':
148
                        /* Text output */
149 8
                        LOG.A_opt = 1;
150 8
                        break;
151
                case 'h':
152
                        /* Usage help */
153 4
                        usage(0);
154
                case 'w':
155
                        /* Write to file */
156 16
                        REPLACE(LOG.w_arg, optarg);
157 16
                        break;
158
                default:
159 304
                        if (!VUT_Arg(vut, opt, optarg))
160 0
                                usage(1);
161
                }
162
        }
163
164 100
        if (optind != argc)
165 4
                usage(1);
166
167 96
        if (vut->D_opt && !LOG.w_arg)
168 4
                VUT_Error(vut, 1, "Missing -w option");
169
170
        /* Setup output */
171 92
        if (LOG.A_opt || !LOG.w_arg)
172 84
                vut->dispatch_f = VSL_PrintTransactions;
173
        else
174 8
                vut->dispatch_f = VSL_WriteTransactions;
175 92
        vut->sighup_f = sighup;
176 92
        if (LOG.w_arg) {
177 16
                openout(LOG.a_opt);
178 12
                AN(LOG.fo);
179 12
                if (vut->D_opt)
180 4
                        vut->sighup_f = rotateout;
181
        } else
182 76
                LOG.fo = stdout;
183 88
        vut->idle_f = flushout;
184
185 88
        VUT_Signal(vut_sighandler);
186 88
        VUT_Setup(vut);
187 36
        VUT_Main(vut);
188 36
        VUT_Fini(&vut);
189
190 36
        (void)flushout(NULL);
191
192 36
        exit(0);
193
}