Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnishapi
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
varnishapi
Commits
98969dd6
Commit
98969dd6
authored
Aug 09, 2018
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
The Log client can now attach to a running Varnish instance.
parent
ea6c227a
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
262 additions
and
8 deletions
+262
-8
e2e_test.go
internal/pkg/vsm/e2e_test.go
+21
-0
vsm.go
internal/pkg/vsm/vsm.go
+10
-0
e2e_test.go
pkg/log/e2e_test.go
+113
-0
log.go
pkg/log/log.go
+100
-8
log.h
pkg/log/log.h
+18
-0
No files found.
internal/pkg/vsm/e2e_test.go
View file @
98969dd6
...
...
@@ -144,3 +144,24 @@ func TestAttachInstance(t *testing.T) {
"non-existent instance"
)
}
}
func
TestPointer
(
t
*
testing
.
T
)
{
v
:=
New
()
defer
v
.
Destroy
()
p
,
err
:=
v
.
Pointer
()
if
err
!=
nil
{
t
.
Error
(
"Pointer():"
,
err
)
}
if
p
==
nil
{
t
.
Error
(
"Pointer() returned nil"
)
}
var
n
*
VSM
if
_
,
err
:=
n
.
Pointer
();
err
==
nil
{
t
.
Error
(
"expected nil.Pointer() to fail"
)
}
uninit
:=
new
(
VSM
)
if
_
,
err
:=
uninit
.
Pointer
();
err
==
nil
{
t
.
Error
(
"expected uninitialized.Pointer() to fail"
)
}
}
internal/pkg/vsm/vsm.go
View file @
98969dd6
...
...
@@ -41,6 +41,7 @@ import (
"errors"
"strconv"
"time"
"unsafe"
)
// An Attacher can attach to a running instance of Varnish. This means
...
...
@@ -168,6 +169,15 @@ func (v *VSM) AttachInstance(inst string, progress bool) error {
return
v
.
attach
(
progress
)
}
// Pointer returns an internal pointer for use by other packages.
// Client code should never use it.
func
(
v
*
VSM
)
Pointer
()
(
unsafe
.
Pointer
,
error
)
{
if
err
:=
v
.
checkNil
();
err
!=
nil
{
return
nil
,
err
}
return
unsafe
.
Pointer
(
v
.
vsm
),
nil
}
/*
func (v *VSM) Get(class string, ident string) (string, error) {
var vf C.struct_vsm_fantom
...
...
pkg/log/e2e_test.go
0 → 100644
View file @
98969dd6
// +build e2e
/*-
* Copyright (c) 2018 UPLEX Nils Goroll Systemoptimierung
* All rights reserved
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
// This test is only run if go test is invoked with a -tags option
// that includes "e2e". It requires that two instances of Varnish are
// running: a default instance (varnishd invoked without the -n
// option), and an instance named "gotest" (varnishd -n "gotest").
package
log
import
(
"testing"
"time"
)
func
TestAttach
(
t
*
testing
.
T
)
{
l
:=
New
()
defer
l
.
Release
()
if
err
:=
l
.
Attach
(
false
);
err
!=
nil
{
t
.
Fatal
(
"Attach(false):"
,
err
)
}
var
n
*
Log
if
err
:=
n
.
Attach
(
false
);
err
==
nil
{
t
.
Error
(
"expected nil.Attach() to fail"
)
}
uninit
:=
new
(
Log
)
if
err
:=
uninit
.
Attach
(
false
);
err
==
nil
{
t
.
Error
(
"expected uninitialized.Attach() to fail"
)
}
}
func
TestAttachProgress
(
t
*
testing
.
T
)
{
l
:=
New
()
defer
l
.
Release
()
if
err
:=
l
.
Attach
(
true
);
err
!=
nil
{
t
.
Error
(
"Attach(true):"
,
err
)
}
}
const
zerosec
=
time
.
Duration
(
0
)
func
TestAttachTmo
(
t
*
testing
.
T
)
{
l
:=
New
()
defer
l
.
Release
()
for
_
,
s
:=
range
[]
int
{
0
,
1
,
-
1
,
^
0
,
int
(
^
uint
(
0
)
>>
1
)}
{
if
e
:=
l
.
AttachTmo
(
time
.
Duration
(
s
)
*
time
.
Second
);
e
!=
nil
{
t
.
Error
(
"AttachTmo():"
,
e
)
}
}
var
n
*
Log
if
err
:=
n
.
AttachTmo
(
zerosec
);
err
==
nil
{
t
.
Error
(
"expected nil.AttachTmo() to fail"
)
}
uninit
:=
new
(
Log
)
if
err
:=
uninit
.
AttachTmo
(
zerosec
);
err
==
nil
{
t
.
Error
(
"expected uninitialized.AttachTmo() to fail"
)
}
}
func
TestAttachInstance
(
t
*
testing
.
T
)
{
l
:=
New
()
defer
l
.
Release
()
if
err
:=
l
.
AttachInstance
(
"gotest"
,
false
);
err
!=
nil
{
t
.
Error
(
"AttachInstance(
\"
gotest
\"
):"
,
err
)
}
f
:=
New
()
defer
f
.
Release
()
if
err
:=
f
.
AttachTmo
(
zerosec
);
err
!=
nil
{
t
.
Error
(
"AttachTmo(0s):"
,
err
)
}
if
err
:=
f
.
AttachInstance
(
"instanceDoesNotExist"
,
false
);
err
==
nil
{
t
.
Error
(
"expected AttachInstance() to fail for a "
+
"non-existent instance"
)
}
var
n
*
Log
if
err
:=
n
.
AttachInstance
(
"gotest"
,
false
);
err
==
nil
{
t
.
Error
(
"expected nil.AttachInstance() to fail"
)
}
uninit
:=
new
(
Log
)
if
err
:=
uninit
.
AttachInstance
(
"gotest"
,
false
);
err
==
nil
{
t
.
Error
(
"expected uninitialized.AttachInstance() to fail"
)
}
}
pkg/log/log.go
View file @
98969dd6
...
...
@@ -36,13 +36,14 @@ package log
*/
import
"C"
// import "uplex.de/varnishapi/internal/pkg/vsm"
import
(
"uplex.de/varnishapi/internal/pkg/vsm"
"errors"
"fmt"
"os"
"regexp"
"time"
"unsafe"
)
...
...
@@ -338,6 +339,8 @@ type Tx struct {
// A Log instance is a client for the native logging interface.
type
Log
struct
{
vsl
*
C
.
struct_VSL_data
vsm
*
vsm
.
VSM
vsmopts
C
.
unsigned
cursor
*
C
.
struct_VSL_cursor
vslq
*
C
.
struct_VSLQ
grp
C
.
enum_VSL_grouping_e
...
...
@@ -358,12 +361,24 @@ func New() *Log {
if
log
.
vsl
==
nil
{
return
nil
}
log
.
vsm
=
nil
log
.
vsmopts
=
C
.
vsl_opt_batch
()
|
C
.
vsl_opt_tail
()
log
.
grp
=
C
.
VSL_g_vxid
log
.
query
=
nil
log
.
cbIdx
=
-
1
return
log
}
func
(
log
*
Log
)
checkNil
()
error
{
if
log
==
nil
{
return
errors
.
New
(
"Log object is nil"
)
}
if
log
.
vsl
==
nil
{
return
errors
.
New
(
"Log object was not initialized via New()"
)
}
return
nil
}
// Release frees native resources associated with this client. You
// should always call Release when you're done using a Log client,
// otherwise there is risk of resource leakage. It is wise to make
...
...
@@ -391,6 +406,83 @@ func (log *Log) Error() string {
return
C
.
GoString
(
C
.
VSL_Error
(
log
.
vsl
))
}
func
(
log
*
Log
)
initVSM
()
error
{
if
err
:=
log
.
checkNil
();
err
!=
nil
{
return
err
}
if
log
.
vsm
==
nil
{
log
.
vsm
=
vsm
.
New
()
if
log
.
vsm
==
nil
{
return
errors
.
New
(
"Cannot initialize for attachment "
+
"to shared memory"
)
}
}
return
nil
}
// AttachTmo sets the timeout for attaching to a Varnish instance.
// The timeout tmo is rounded to seconds toward 0s. If tmo >= 0s, then
// wait that many seconds to attach. If the tmo < 0s, wait
// indefinitely. By default, the Varnish default timeout holds (5s in
// recent Varnish versions).
func
(
log
*
Log
)
AttachTmo
(
tmo
time
.
Duration
)
error
{
if
err
:=
log
.
initVSM
();
err
!=
nil
{
return
err
}
return
log
.
vsm
.
AttachTmo
(
tmo
)
}
func
(
log
*
Log
)
setCursor
()
error
{
p
,
err
:=
log
.
vsm
.
Pointer
()
if
err
!=
nil
{
return
err
}
vsmp
:=
(
*
C
.
struct_vsm
)(
p
)
C
.
VSL_ResetError
(
log
.
vsl
)
log
.
cursor
=
C
.
VSL_CursorVSM
(
log
.
vsl
,
vsmp
,
log
.
vsmopts
)
if
log
.
cursor
==
nil
{
return
log
}
return
nil
}
// Attach to the default instance of Varnish -- the instance of
// varnishd invoked without the -n option.
//
// If progress is true, a dot ('.') is printed to standard output for
// each second waiting for the attach to succeed. If the attach fails
// after timeout, a newline is printed. If progress is false, there is
// no such output.
func
(
log
*
Log
)
Attach
(
progress
bool
)
error
{
if
err
:=
log
.
initVSM
();
err
!=
nil
{
return
err
}
if
err
:=
log
.
vsm
.
Attach
(
progress
);
err
!=
nil
{
return
err
}
if
err
:=
log
.
setCursor
();
err
!=
nil
{
return
nil
}
return
nil
}
// AttachInstance attaches to a named instance of Varnish, where name
// corresponds to the -n argument in the invocation of varnishd.
//
// The progress argument has the same meaning as for Attach.
func
(
log
*
Log
)
AttachInstance
(
name
string
,
progress
bool
)
error
{
if
err
:=
log
.
initVSM
();
err
!=
nil
{
return
err
}
if
err
:=
log
.
vsm
.
AttachInstance
(
name
,
progress
);
err
!=
nil
{
return
err
}
if
err
:=
log
.
setCursor
();
err
!=
nil
{
return
nil
}
return
nil
}
// AttachFile attaches the client for reading from the binary log file
// located at path, as written by varnishlog -w.
//
...
...
pkg/log/log.h
View file @
98969dd6
...
...
@@ -97,4 +97,22 @@ unsafe(enum VSL_tag_e tag)
return
(
VSL_tagflags
[
tag
]
&
SLT_F_UNSAFE
);
}
static
inline
unsigned
vsl_opt_batch
()
{
return
VSL_COPT_BATCH
;
}
static
inline
unsigned
vsl_opt_tail
()
{
return
VSL_COPT_TAIL
;
}
static
inline
unsigned
vsl_opt_tailstop
()
{
return
VSL_COPT_TAILSTOP
;
}
#endif
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