Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
d52227e6
Commit
d52227e6
authored
Dec 20, 2018
by
Guillaume Quintard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a -j switch to varnishlog to output JSON
Transaction blocks are line-delimited.
parent
ec554a0f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
219 additions
and
2 deletions
+219
-2
varnishlog.c
bin/varnishlog/varnishlog.c
+8
-1
varnishlog_options.h
bin/varnishlog/varnishlog_options.h
+6
-0
vsl.h
include/vapi/vsl.h
+13
-0
libvarnishapi.map
lib/libvarnishapi/libvarnishapi.map
+1
-0
vsl.c
lib/libvarnishapi/vsl.c
+191
-1
No files found.
bin/varnishlog/varnishlog.c
View file @
d52227e6
...
...
@@ -58,6 +58,7 @@ static struct log {
/* Options */
int
a_opt
;
int
A_opt
;
int
j_opt
;
char
*
w_arg
;
/* State */
...
...
@@ -125,6 +126,10 @@ main(int argc, char * const *argv)
case
'h'
:
/* Usage help */
VUT_Usage
(
vut
,
&
vopt_spec
,
0
);
case
'j'
:
/* JSON output */
LOG
.
j_opt
=
1
;
break
;
case
'w'
:
/* Write to file */
REPLACE
(
LOG
.
w_arg
,
optarg
);
...
...
@@ -142,7 +147,9 @@ main(int argc, char * const *argv)
VUT_Error
(
vut
,
1
,
"Missing -w option"
);
/* Setup output */
if
(
LOG
.
A_opt
||
!
LOG
.
w_arg
)
if
(
LOG
.
j_opt
)
vut
->
dispatch_f
=
VSL_PrintJSONTransactions
;
else
if
(
LOG
.
A_opt
||
!
LOG
.
w_arg
)
vut
->
dispatch_f
=
VSL_PrintTransactions
;
else
vut
->
dispatch_f
=
VSL_WriteTransactions
;
...
...
bin/varnishlog/varnishlog_options.h
View file @
d52227e6
...
...
@@ -42,6 +42,11 @@
" data in ascii format." \
)
#define LOG_OPT_j \
VOPT("j", "[-j]", "LDJSON output", \
"Print each record block as a JSON object" \
)
#define LOG_OPT_w \
VOPT("w:", "[-w <filename>]", "Output filename", \
"Redirect output to file. The file will be overwritten" \
...
...
@@ -63,6 +68,7 @@ VUT_GLOBAL_OPT_D
VUT_OPT_g
VUT_OPT_h
VSL_OPT_i
LOG_OPT_j
VSL_OPT_I
VUT_OPT_k
VSL_OPT_L
...
...
include/vapi/vsl.h
View file @
d52227e6
...
...
@@ -439,6 +439,19 @@ VSLQ_dispatch_f VSL_PrintTransactions;
* !=0: Return value from either VSL_Next or VSL_Print
*/
VSLQ_dispatch_f
VSL_PrintJSONTransactions
;
/* Prints the array ptrans as one JSON object, on one line.
*
* Arguments:
* vsl: The VSL_data context
* cp: A NULL-terminated array of VSL_cursor pointers
* fo: A FILE* pointer, stdout if NULL
*
* Return values:
* 0: OK
* !=0: Return value from either VSL_Next or VSL_Print
*/
FILE
*
VSL_WriteOpen
(
struct
VSL_data
*
vsl
,
const
char
*
name
,
int
append
,
int
unbuffered
);
/*
...
...
lib/libvarnishapi/libvarnishapi.map
View file @
d52227e6
...
...
@@ -89,6 +89,7 @@ LIBVARNISHAPI_2.0 {
VSL_Next;
VSL_Print;
VSL_PrintAll;
VSL_PrintJSONTransactions;
VSL_PrintTerse;
VSL_PrintTransactions;
VSL_ResetCursor;
...
...
lib/libvarnishapi/vsl.c
View file @
d52227e6
...
...
@@ -216,6 +216,16 @@ static const char * const VSL_transactions[VSL_t__MAX] = {
[
VSL_t_raw
]
=
"<< Record >>"
,
};
static
const
char
*
const
VSL_transactionsTerse
[
VSL_t__MAX
]
=
{
/* 12345678901234 */
[
VSL_t_unknown
]
=
"Unknown"
,
[
VSL_t_sess
]
=
"Session"
,
[
VSL_t_req
]
=
"Request"
,
[
VSL_t_bereq
]
=
"BeReq"
,
[
VSL_t_raw
]
=
"Record"
,
};
#define VSL_PRINT(...) \
do { \
if (0 > fprintf(__VA_ARGS__)) \
...
...
@@ -317,12 +327,192 @@ VSL_PrintAll(struct VSL_data *vsl, const struct VSL_cursor *c, void *fo)
return
(
i
);
if
(
!
VSL_Match
(
vsl
,
c
))
continue
;
i
=
VSL_Print
(
vsl
,
c
,
fo
);
i
=
VSL_Print
(
vsl
,
c
,
fo
);
if
(
i
!=
0
)
return
(
i
);
}
}
static
int
vsl_print_json
(
FILE
*
fo
,
unsigned
len
,
const
char
*
data
,
unsigned
unsafe
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
len
&&
(
unsafe
||
data
[
i
])
;
i
++
)
{
switch
(
data
[
i
])
{
#define ESCAPE(c, ec) \
case c: \
VSL_PRINT(fo, ec); \
i++; \
break;
ESCAPE
(
'\\'
,
"
\\\\
"
);
ESCAPE
(
'\"'
,
"
\\\"
"
);
ESCAPE
(
'\b'
,
"
\\
b"
);
ESCAPE
(
'\f'
,
"
\\
f"
);
ESCAPE
(
'\n'
,
"
\\
n"
);
ESCAPE
(
'\r'
,
"
\\
r"
);
ESCAPE
(
'\t'
,
"
\\
t"
);
#undef ESCAPE
default:
if
(
!
unsafe
||
(
data
[
i
]
>=
' '
&&
data
[
i
]
<=
'~'
))
VSL_PRINT
(
fo
,
"%c"
,
data
[
i
]);
else
VSL_PRINT
(
fo
,
"%%%02x"
,
(
unsigned
char
)
data
[
i
]);
}
}
return
(
0
);
}
static
int
VSL_PrintJSON
(
const
struct
VSL_data
*
vsl
,
const
struct
VSL_cursor
*
c
,
void
*
fo
)
{
enum
VSL_tag_e
tag
;
unsigned
len
;
const
char
*
data
;
CHECK_OBJ_NOTNULL
(
vsl
,
VSL_MAGIC
);
if
(
c
==
NULL
||
c
->
rec
.
ptr
==
NULL
)
return
(
0
);
if
(
fo
==
NULL
)
fo
=
stdout
;
tag
=
VSL_TAG
(
c
->
rec
.
ptr
);
len
=
VSL_LEN
(
c
->
rec
.
ptr
);
data
=
VSL_CDATA
(
c
->
rec
.
ptr
);
VSL_PRINT
(
fo
,
"{
\"
tag
\"
:
\"
%s
\"
,
\"
value
\"
:
\"
"
,
VSL_tags
[
tag
]);
if
(
VSL_tagflags
[
tag
]
&
SLT_F_UNSAFE
)
(
void
)
vsl_print_json
(
fo
,
len
,
data
,
1
);
else
if
(
VSL_tagflags
[
tag
]
&
SLT_F_BINARY
)
(
void
)
vsl_print_binary
(
fo
,
len
,
data
);
else
vsl_print_json
(
fo
,
(
int
)
len
,
data
,
0
);
VSL_PRINT
(
fo
,
"
\"
}"
);
return
(
0
);
}
int
v_matchproto_
(
VSLQ_dispatch_f
)
VSL_PrintJSONTransactions
(
struct
VSL_data
*
vsl
,
struct
VSL_transaction
*
const
ptu
[],
void
*
fo
)
{
struct
VSL_transaction
*
t
,
*
swap
,
**
pt
,
**
pto
;
int
i
,
stop
,
next_slot
,
current_root
;
int
delim
,
level
;
CHECK_OBJ_NOTNULL
(
vsl
,
VSL_MAGIC
);
if
(
fo
==
NULL
)
fo
=
stdout
;
if
(
ptu
[
0
]
==
NULL
)
return
(
0
);
/* assume the first item is our root */
next_slot
=
1
;
current_root
=
0
;
/* first, we need to reorder the transaction array to
* be depth first, so we make a copy */
for
(
stop
=
0
;
ptu
[
stop
];
stop
++
)
{}
pto
=
pt
=
malloc
((
stop
+
1
)
*
sizeof
(
t
));
pto
=
pt
;
AN
(
pt
);
memcpy
(
pt
,
ptu
,
(
stop
+
1
)
*
sizeof
(
t
));
/* then reorder */
while
(
next_slot
<
stop
)
{
// find a node connected to the current root
for
(
i
=
next_slot
;
i
<
stop
;
i
++
)
{
if
(
pt
[
i
]
->
vxid_parent
!=
pt
[
current_root
]
->
vxid
)
continue
;
swap
=
pt
[
next_slot
];
pt
[
next_slot
]
=
pt
[
i
];
pt
[
i
]
=
swap
;
current_root
=
next_slot
;
next_slot
++
;
i
=
next_slot
;
}
/* if we could not find a child for the current root,
* back up a little bit, or if the root is already at index 0,
* we are done
* note: we may back up to siblings or nephews (nieces?), and
* do superfluous work, but I'm not sure it's worth refinding
* the parent of current_root by retraversing the array again
*/
if
(
current_root
==
0
)
break
;
else
current_root
--
;
}
for
(
t
=
pt
[
0
];
t
!=
NULL
;
t
=
*++
pt
)
{
delim
=
0
;
if
(
vsl
->
c_opt
||
vsl
->
b_opt
)
{
switch
(
t
->
type
)
{
case
VSL_t_req
:
if
(
!
vsl
->
c_opt
)
continue
;
break
;
case
VSL_t_bereq
:
if
(
!
vsl
->
b_opt
)
continue
;
break
;
case
VSL_t_raw
:
break
;
default:
continue
;
}
}
VSL_PRINT
(
fo
,
"{
\"
id
\"
: %u,
\"
type
\"
:
\"
%s
\"
,"
,
t
->
vxid
,
VSL_transactionsTerse
[
t
->
type
]);
VSL_PRINT
(
fo
,
"
\"
records
\"
: [ "
);
while
(
1
)
{
/* Print records */
i
=
VSL_Next
(
t
->
c
);
if
(
i
<
0
)
{
free
(
pt
);
return
(
i
);
}
if
(
i
==
0
)
break
;
if
(
!
VSL_Match
(
vsl
,
t
->
c
))
continue
;
if
(
delim
)
VSL_PRINT
(
fo
,
", "
);
i
=
VSL_PrintJSON
(
vsl
,
t
->
c
,
fo
);
if
(
i
!=
0
)
{
free
(
pt
);
return
(
i
);
}
delim
=
1
;
}
VSL_PRINT
(
fo
,
" ]"
);
/* peek ahead and use the level differences to join
* transactions */
(
void
)
level
;
(
void
)
pto
;
if
(
!
pt
[
1
])
{
VSL_PRINT
(
fo
,
" }"
);
for
(
level
=
pto
[
0
]
->
level
;
level
<
t
->
level
;
level
++
)
VSL_PRINT
(
fo
,
" ] }"
);
VSL_PRINT
(
fo
,
"
\n
"
);
}
else
if
(
pt
[
1
]
->
level
<=
t
->
level
)
{
VSL_PRINT
(
fo
,
" }"
);
for
(
level
=
t
->
level
;
level
>
pt
[
1
]
->
level
;
level
--
)
VSL_PRINT
(
fo
,
" ] }"
);
VSL_PRINT
(
fo
,
", "
);
}
else
if
(
pt
[
1
]
->
level
>
t
->
level
)
{
assert
(
pt
[
1
]
->
level
==
t
->
level
+
1
);
VSL_PRINT
(
fo
,
",
\"
links
\"
: [ "
);
}
}
return
(
0
);
}
int
v_matchproto_
(
VSLQ_dispatch_f
)
VSL_PrintTransactions
(
struct
VSL_data
*
vsl
,
struct
VSL_transaction
*
const
pt
[],
void
*
fo
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment