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 6
usage(int status)
69
{
70
        const char **opt;
71 6
        fprintf(stderr, "Usage: %s <options>\n\n", vut->progname);
72 6
        fprintf(stderr, "Options:\n");
73 150
        for (opt = vopt_spec.vopt_usage; *opt != NULL; opt += 2)
74 144
                fprintf(stderr, " %-25s %s\n", *opt, *(opt + 1));
75 6
        exit(status);
76
}
77
78
static void
79 15
openout(int append)
80
{
81
82 15
        AN(LOG.w_arg);
83 15
        if (LOG.A_opt)
84 6
                LOG.fo = fopen(LOG.w_arg, append ? "a" : "w");
85
        else
86 9
                LOG.fo = VSL_WriteOpen(vut->vsl, LOG.w_arg, append, 0);
87 15
        if (LOG.fo == NULL)
88 6
                VUT_Error(vut, 2, "Cannot open output file (%s)",
89 6
                    LOG.A_opt ? strerror(errno) : VSL_Error(vut->vsl));
90 12
        vut->dispatch_priv = LOG.fo;
91 12
}
92
93
static int v_matchproto_(VUT_cb_f)
94 3
rotateout(struct VUT *v)
95
{
96
97 3
        assert(v == vut);
98 3
        AN(LOG.w_arg);
99 3
        AN(LOG.fo);
100 3
        fclose(LOG.fo);
101 3
        openout(1);
102 3
        AN(LOG.fo);
103 3
        return (0);
104
}
105
106
static int v_matchproto_(VUT_cb_f)
107 4707
flushout(struct VUT *v)
108
{
109
110 4707
        assert(v == vut);
111 4707
        AN(LOG.fo);
112 4707
        if (fflush(LOG.fo))
113 0
                return (-5);
114 4707
        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 9
vut_sighandler(int sig)
126
{
127
128 9
        if (vut != NULL)
129 9
                VUT_Signaled(vut, sig);
130 9
}
131
132
int
133 123
main(int argc, char * const *argv)
134
{
135
        int opt;
136
137 123
        vut = VUT_InitProg(argc, argv, &vopt_spec);
138 117
        AN(vut);
139 117
        memset(&LOG, 0, sizeof LOG);
140
141 441
        while ((opt = getopt(argc, argv, vopt_spec.vopt_optstring)) != -1) {
142 249
                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 6
                        LOG.A_opt = 1;
150 6
                        break;
151
                case 'h':
152
                        /* Usage help */
153 3
                        usage(0);
154
                case 'w':
155
                        /* Write to file */
156 12
                        REPLACE(LOG.w_arg, optarg);
157 12
                        break;
158
                default:
159 228
                        if (!VUT_Arg(vut, opt, optarg))
160 0
                                usage(1);
161
                }
162
        }
163
164 75
        if (optind != argc)
165 3
                usage(1);
166
167 72
        if (vut->D_opt && !LOG.w_arg)
168 3
                VUT_Error(vut, 1, "Missing -w option");
169
170
        /* Setup output */
171 69
        if (LOG.A_opt || !LOG.w_arg)
172 63
                vut->dispatch_f = VSL_PrintTransactions;
173
        else
174 6
                vut->dispatch_f = VSL_WriteTransactions;
175 69
        vut->sighup_f = sighup;
176 69
        if (LOG.w_arg) {
177 12
                openout(LOG.a_opt);
178 9
                AN(LOG.fo);
179 9
                if (vut->D_opt)
180 3
                        vut->sighup_f = rotateout;
181
        } else
182 57
                LOG.fo = stdout;
183 66
        vut->idle_f = flushout;
184
185 66
        VUT_Signal(vut_sighandler);
186 66
        VUT_Setup(vut);
187 27
        VUT_Main(vut);
188 27
        VUT_Fini(&vut);
189
190 27
        (void)flushout(NULL);
191
192 27
        exit(0);
193
}