Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
63c2f263
Commit
63c2f263
authored
Jul 05, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
a4cfd3bb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
65 deletions
+67
-65
go/xcommon/tracing/cmd/gotrace/gotrace.go
go/xcommon/tracing/cmd/gotrace/gotrace.go
+55
-56
go/xcommon/tracing/tracing.go
go/xcommon/tracing/tracing.go
+12
-9
No files found.
go/xcommon/tracing/cmd/gotrace/gotrace.go
View file @
63c2f263
...
@@ -18,7 +18,10 @@
...
@@ -18,7 +18,10 @@
// See https://www.nexedi.com/licensing for rationale and options.
// See https://www.nexedi.com/licensing for rationale and options.
/*
/*
gotrace gen generates code according to tracing annotations and imports
gotrace TODO
gen generates code according to tracing annotations and imports
list lists tracepoints defined in a package
gotrace gen package
gotrace gen package
gotrace list package TODO
gotrace list package TODO
...
@@ -56,8 +59,8 @@ import (
...
@@ -56,8 +59,8 @@ import (
// traceEvent represents 1 trace:event definition
// traceEvent represents 1 trace:event definition
type
traceEvent
struct
{
type
traceEvent
struct
{
Pos
token
.
Position
Pos
token
.
Position
Pkgt
*
Package
// package this trace event is part of
Pkgt
*
Package
// package this trace event is part of
// declaration of function to signal the event
// declaration of function to signal the event
// the declaration is constructed on the fly via converting e.g.
// the declaration is constructed on the fly via converting e.g.
...
@@ -75,17 +78,17 @@ type traceEvent struct {
...
@@ -75,17 +78,17 @@ type traceEvent struct {
// traceImport represents 1 trace:import directive
// traceImport represents 1 trace:import directive
type
traceImport
struct
{
type
traceImport
struct
{
Pos
token
.
Position
Pos
token
.
Position
PkgName
string
// "" if import name was not explicitly specified
PkgName
string
// "" if import name was not explicitly specified
PkgPath
string
PkgPath
string
}
}
// traceImported represents 1 imported trace:event
// traceImported represents 1 imported trace:event
type
traceImported
struct
{
type
traceImported
struct
{
*
traceEvent
// original event
*
traceEvent
// original event
ImportSpec
*
traceImport
// imported via this spec
ImportSpec
*
traceImport
// imported via this spec
ImporterPkg
*
types
.
Package
// from this package
ImporterPkg
*
types
.
Package
// from this package
ImportedAs
map
[
string
]
string
// where some packages are imported as named (pkgpath -> pkgname)
ImportedAs
map
[
string
]
string
// where some packages are imported as named (pkgpath -> pkgname)
}
}
// Package represents tracing-related information about a package
// Package represents tracing-related information about a package
...
@@ -106,7 +109,6 @@ type Package struct {
...
@@ -106,7 +109,6 @@ type Package struct {
traceTypeInfo
*
types
.
Info
// typeinfo for ^^^
traceTypeInfo
*
types
.
Info
// typeinfo for ^^^
}
}
// parseTraceEvent parses trace event definition into traceEvent
// parseTraceEvent parses trace event definition into traceEvent
// text is text argument after "//trace:event "
// text is text argument after "//trace:event "
func
(
p
*
Package
)
parseTraceEvent
(
srcfile
*
ast
.
File
,
pos
token
.
Position
,
text
string
)
(
*
traceEvent
,
error
)
{
func
(
p
*
Package
)
parseTraceEvent
(
srcfile
*
ast
.
File
,
pos
token
.
Position
,
text
string
)
(
*
traceEvent
,
error
)
{
...
@@ -237,30 +239,30 @@ func packageTrace(prog *loader.Program, pkgi *loader.PackageInfo) (*Package, err
...
@@ -237,30 +239,30 @@ func packageTrace(prog *loader.Program, pkgi *loader.PackageInfo) (*Package, err
// prepare Package with typechecker ready to typecheck trace files
// prepare Package with typechecker ready to typecheck trace files
// (to get trace func argument types)
// (to get trace func argument types)
tconf
:=
&
types
.
Config
{
tconf
:=
&
types
.
Config
{
Importer
:
&
progImporter
{
prog
},
Importer
:
&
progImporter
{
prog
},
// to ignore traceXXX() calls from original package code
// to ignore traceXXX() calls from original package code
IgnoreFuncBodies
:
true
,
IgnoreFuncBodies
:
true
,
// we take imports from original source file verbatim,
// we take imports from original source file verbatim,
// but most of them probably won't be used.
// but most of them probably won't be used.
DisableUnusedImportCheck
:
true
,
DisableUnusedImportCheck
:
true
,
}
}
// tfset := token.NewFileSet() // XXX ok to separate or use original package fset?
// tfset := token.NewFileSet() // XXX ok to separate or use original package fset?
tpkg
:=
types
.
NewPackage
(
pkgi
.
Pkg
.
Path
(),
pkgi
.
Pkg
.
Name
())
tpkg
:=
types
.
NewPackage
(
pkgi
.
Pkg
.
Path
(),
pkgi
.
Pkg
.
Name
())
tinfo
:=
&
types
.
Info
{
Types
:
make
(
map
[
ast
.
Expr
]
types
.
TypeAndValue
)}
tinfo
:=
&
types
.
Info
{
Types
:
make
(
map
[
ast
.
Expr
]
types
.
TypeAndValue
)}
p
:=
&
Package
{
p
:=
&
Package
{
Pkgi
:
pkgi
,
Pkgi
:
pkgi
,
// traceFset: tfset,
// traceFset: tfset,
// traceChecker: types.NewChecker(tconf, tfset, tpkg, tinfo),
// traceChecker: types.NewChecker(tconf, tfset, tpkg, tinfo),
// XXX vvv do we need separate field for traceFset if it is = prog.Fset?
// XXX vvv do we need separate field for traceFset if it is = prog.Fset?
traceFset
:
prog
.
Fset
,
traceFset
:
prog
.
Fset
,
traceChecker
:
types
.
NewChecker
(
tconf
,
prog
.
Fset
,
tpkg
,
tinfo
),
traceChecker
:
types
.
NewChecker
(
tconf
,
prog
.
Fset
,
tpkg
,
tinfo
),
tracePkg
:
tpkg
,
tracePkg
:
tpkg
,
traceTypeInfo
:
tinfo
,
traceTypeInfo
:
tinfo
,
}
}
// preload original package files into tracing package
// preload original package files into tracing package
...
@@ -276,8 +278,8 @@ func packageTrace(prog *loader.Program, pkgi *loader.PackageInfo) (*Package, err
...
@@ -276,8 +278,8 @@ func packageTrace(prog *loader.Program, pkgi *loader.PackageInfo) (*Package, err
// already preprocessed results with comments stripped, not original source.
// already preprocessed results with comments stripped, not original source.
// Maybe in some time it will be possible to have AST of original source:
// Maybe in some time it will be possible to have AST of original source:
// https://github.com/golang/go/issues/16623
// https://github.com/golang/go/issues/16623
for
_
,
file
:=
range
pkgi
.
Files
{
// ast.File
for
_
,
file
:=
range
pkgi
.
Files
{
// ast.File
for
_
,
commgroup
:=
range
file
.
Comments
{
// ast.CommentGroup
for
_
,
commgroup
:=
range
file
.
Comments
{
// ast.CommentGroup
for
_
,
comment
:=
range
commgroup
.
List
{
// ast.Comment
for
_
,
comment
:=
range
commgroup
.
List
{
// ast.Comment
pos
:=
prog
.
Fset
.
Position
(
comment
.
Slash
)
pos
:=
prog
.
Fset
.
Position
(
comment
.
Slash
)
//fmt.Printf("%v %q\n", pos, comment.Text)
//fmt.Printf("%v %q\n", pos, comment.Text)
...
@@ -333,17 +335,18 @@ func packageTrace(prog *loader.Program, pkgi *loader.PackageInfo) (*Package, err
...
@@ -333,17 +335,18 @@ func packageTrace(prog *loader.Program, pkgi *loader.PackageInfo) (*Package, err
// byEventName provides []*traceEvent ordering by event name
// byEventName provides []*traceEvent ordering by event name
type
byEventName
[]
*
traceEvent
type
byEventName
[]
*
traceEvent
func
(
v
byEventName
)
Less
(
i
,
j
int
)
bool
{
return
v
[
i
]
.
Name
.
Name
<
v
[
j
]
.
Name
.
Name
}
func
(
v
byEventName
)
Less
(
i
,
j
int
)
bool
{
return
v
[
i
]
.
Name
.
Name
<
v
[
j
]
.
Name
.
Name
}
func
(
v
byEventName
)
Swap
(
i
,
j
int
)
{
v
[
i
],
v
[
j
]
=
v
[
j
],
v
[
i
]
}
func
(
v
byEventName
)
Swap
(
i
,
j
int
)
{
v
[
i
],
v
[
j
]
=
v
[
j
],
v
[
i
]
}
func
(
v
byEventName
)
Len
()
int
{
return
len
(
v
)
}
func
(
v
byEventName
)
Len
()
int
{
return
len
(
v
)
}
// byPkgPath provides []*traceImport ordering by package path
// byPkgPath provides []*traceImport ordering by package path
type
byPkgPath
[]
*
traceImport
type
byPkgPath
[]
*
traceImport
func
(
v
byPkgPath
)
Less
(
i
,
j
int
)
bool
{
return
v
[
i
]
.
PkgPath
<
v
[
j
]
.
PkgPath
}
func
(
v
byPkgPath
)
Less
(
i
,
j
int
)
bool
{
return
v
[
i
]
.
PkgPath
<
v
[
j
]
.
PkgPath
}
func
(
v
byPkgPath
)
Swap
(
i
,
j
int
)
{
v
[
i
],
v
[
j
]
=
v
[
j
],
v
[
i
]
}
func
(
v
byPkgPath
)
Swap
(
i
,
j
int
)
{
v
[
i
],
v
[
j
]
=
v
[
j
],
v
[
i
]
}
func
(
v
byPkgPath
)
Len
()
int
{
return
len
(
v
)
}
func
(
v
byPkgPath
)
Len
()
int
{
return
len
(
v
)
}
// SplitTests splits package into main and test parts, each covering trace-related things accordingly
// SplitTests splits package into main and test parts, each covering trace-related things accordingly
func
(
p
*
Package
)
SplitTests
()
(
testPkg
*
Package
)
{
func
(
p
*
Package
)
SplitTests
()
(
testPkg
*
Package
)
{
__
:=
*
p
__
:=
*
p
...
@@ -376,8 +379,6 @@ func (p *Package) SplitTests() (testPkg *Package) {
...
@@ -376,8 +379,6 @@ func (p *Package) SplitTests() (testPkg *Package) {
return
testPkg
return
testPkg
}
}
// ----------------------------------------
// ----------------------------------------
// Argv returns comma-separated argument-list
// Argv returns comma-separated argument-list
...
@@ -401,7 +402,7 @@ func (te *traceEvent) ArgvTyped() string {
...
@@ -401,7 +402,7 @@ func (te *traceEvent) ArgvTyped() string {
// ArgvTypedRelativeTo returns argument list with types qualified relative to specified package
// ArgvTypedRelativeTo returns argument list with types qualified relative to specified package
// importedAs specifies under which name a package was imported, if name was explicitly set
// importedAs specifies under which name a package was imported, if name was explicitly set
func
(
te
*
traceEvent
)
ArgvTypedRelativeTo
(
pkg
*
types
.
Package
,
importedAs
map
[
string
/*pkgpath*/
]
string
/*
pkgname*/
)
string
{
func
(
te
*
traceEvent
)
ArgvTypedRelativeTo
(
pkg
*
types
.
Package
,
importedAs
map
[
string
]
string
/*pkgpath ->
pkgname*/
)
string
{
argv
:=
[]
string
{}
argv
:=
[]
string
{}
// default qualifier - relative to original package
// default qualifier - relative to original package
...
@@ -437,10 +438,9 @@ func (te *traceEvent) ArgvTypedRelativeTo(pkg *types.Package, importedAs map[str
...
@@ -437,10 +438,9 @@ func (te *traceEvent) ArgvTypedRelativeTo(pkg *types.Package, importedAs map[str
return
strings
.
Join
(
argv
,
", "
)
return
strings
.
Join
(
argv
,
", "
)
}
}
// NeedPkgv returns packages that are needed for argument types
// NeedPkgv returns packages that are needed for argument types
func
(
te
*
traceEvent
)
NeedPkgv
()
[]
string
{
func
(
te
*
traceEvent
)
NeedPkgv
()
[]
string
{
pkgset
:=
StrSet
{
/*pkgpath*/
}
pkgset
:=
StrSet
{
/*pkgpath*/
}
qf
:=
func
(
pkg
*
types
.
Package
)
string
{
qf
:=
func
(
pkg
*
types
.
Package
)
string
{
// if we are called - pkg is used
// if we are called - pkg is used
pkgset
.
Add
(
pkg
.
Path
())
pkgset
.
Add
(
pkg
.
Path
())
...
@@ -465,7 +465,6 @@ func (ti *traceImport) ImportSpec() string {
...
@@ -465,7 +465,6 @@ func (ti *traceImport) ImportSpec() string {
return
t
return
t
}
}
// traceEventCodeTmpl is code template generated for one trace event
// traceEventCodeTmpl is code template generated for one trace event
var
traceEventCodeTmpl
=
template
.
Must
(
template
.
New
(
"traceevent"
)
.
Parse
(
`
var
traceEventCodeTmpl
=
template
.
Must
(
template
.
New
(
"traceevent"
)
.
Parse
(
`
// traceevent: {{.Name}}({{.ArgvTyped}})
// traceevent: {{.Name}}({{.ArgvTyped}})
...
@@ -614,10 +613,10 @@ func NewProgram(ctxt *build.Context, cwd string) *Program {
...
@@ -614,10 +613,10 @@ func NewProgram(ctxt *build.Context, cwd string) *Program {
p
:=
&
Program
{}
p
:=
&
Program
{}
p
.
loaderConf
=
&
loader
.
Config
{
p
.
loaderConf
=
&
loader
.
Config
{
ParserMode
:
parser
.
ParseComments
,
ParserMode
:
parser
.
ParseComments
,
TypeCheckFuncBodies
:
func
(
path
string
)
bool
{
return
false
},
TypeCheckFuncBodies
:
func
(
path
string
)
bool
{
return
false
},
Build
:
&
ctxtNoZTrace
,
Build
:
&
ctxtNoZTrace
,
Cwd
:
cwd
,
Cwd
:
cwd
,
}
}
return
p
return
p
...
@@ -671,7 +670,8 @@ func (p *Program) ImportWithTests(pkgpath string) (prog *loader.Program, pkgi *l
...
@@ -671,7 +670,8 @@ func (p *Program) ImportWithTests(pkgpath string) (prog *loader.Program, pkgi *l
if
len
(
prog
.
Created
)
>
0
{
if
len
(
prog
.
Created
)
>
0
{
xtestPkgi
=
prog
.
Created
[
0
]
xtestPkgi
=
prog
.
Created
[
0
]
}
}
for
_
,
pkgi
=
range
prog
.
Imported
{}
for
_
,
pkgi
=
range
prog
.
Imported
{
}
return
prog
,
pkgi
,
xtestPkgi
,
nil
return
prog
,
pkgi
,
xtestPkgi
,
nil
}
}
...
@@ -721,14 +721,13 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
...
@@ -721,14 +721,13 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
return
xerr
.
Merge
(
err1
,
err2
,
err3
)
return
xerr
.
Merge
(
err1
,
err2
,
err3
)
}
}
// tracegen1 generates code according to tracing directives for a (sub)package @pkgpath
// tracegen1 generates code according to tracing directives for a (sub)package @pkgpath
// subpackage is either original package, testing code, or external test package
// subpackage is either original package, testing code, or external test package
func
tracegen1
(
P
*
Program
,
tpkg
*
Package
,
pkgdir
string
,
kind
string
)
error
{
func
tracegen1
(
P
*
Program
,
tpkg
*
Package
,
pkgdir
string
,
kind
string
)
error
{
var
err
error
var
err
error
// write ztrace.go with code generated for trace events and imports
// write ztrace.go with code generated for trace events and imports
ztrace_go
:=
filepath
.
Join
(
pkgdir
,
"ztrace"
+
kind
+
".go"
)
ztrace_go
:=
filepath
.
Join
(
pkgdir
,
"ztrace"
+
kind
+
".go"
)
if
len
(
tpkg
.
Eventv
)
==
0
&&
len
(
tpkg
.
Importv
)
==
0
{
if
len
(
tpkg
.
Eventv
)
==
0
&&
len
(
tpkg
.
Importv
)
==
0
{
err
=
removeFile
(
ztrace_go
)
err
=
removeFile
(
ztrace_go
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -797,11 +796,12 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
...
@@ -797,11 +796,12 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
}
}
// verify export hash so link fails if it gets out of sync with imported package
// verify export hash so link fails if it gets out of sync with imported package
err
=
traceEventImportCheckTmpl
.
Execute
(
text
,
struct
{
err
=
traceEventImportCheckTmpl
.
Execute
(
text
,
struct
{
ImportSpec
*
traceImport
ImportSpec
*
traceImport
ExportHash
string
}{
ExportHash
string
timport
,
}{
traceExportHash
(
impPkg
,
""
/*regular package*/
)})
timport
,
traceExportHash
(
impPkg
,
""
/*regular package*/
)})
text
.
emit
(
""
)
text
.
emit
(
""
)
...
@@ -809,10 +809,10 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
...
@@ -809,10 +809,10 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
for
_
,
event
:=
range
impPkg
.
Eventv
{
for
_
,
event
:=
range
impPkg
.
Eventv
{
needPkg
.
Add
(
event
.
NeedPkgv
()
...
)
needPkg
.
Add
(
event
.
NeedPkgv
()
...
)
importedEvent
:=
traceImported
{
importedEvent
:=
traceImported
{
traceEvent
:
event
,
traceEvent
:
event
,
ImportSpec
:
timport
,
ImportSpec
:
timport
,
ImporterPkg
:
tpkg
.
Pkgi
.
Pkg
,
ImporterPkg
:
tpkg
.
Pkgi
.
Pkg
,
ImportedAs
:
importedAs
,
ImportedAs
:
importedAs
,
}
}
err
=
traceEventImportTmpl
.
Execute
(
text
,
importedEvent
)
err
=
traceEventImportTmpl
.
Execute
(
text
,
importedEvent
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -822,7 +822,7 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
...
@@ -822,7 +822,7 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
}
}
// finish prologue with needed imports
// finish prologue with needed imports
needPkg
.
Delete
(
tpkg
.
Pkgi
.
Pkg
.
Path
())
// our pkg - no need to import
needPkg
.
Delete
(
tpkg
.
Pkgi
.
Pkg
.
Path
())
// our pkg - no need to import
needPkgv
:=
needPkg
.
Itemv
()
needPkgv
:=
needPkg
.
Itemv
()
if
len
(
needPkgv
)
>
0
{
if
len
(
needPkgv
)
>
0
{
prologue
.
emit
(
""
)
prologue
.
emit
(
""
)
...
@@ -846,7 +846,7 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
...
@@ -846,7 +846,7 @@ func tracegen1(P *Program, tpkg *Package, pkgdir string, kind string) error {
}
}
// write empty ztrace.s so go:linkname works, if there are trace imports
// write empty ztrace.s so go:linkname works, if there are trace imports
ztrace_s
:=
filepath
.
Join
(
pkgdir
,
"ztrace"
+
kind
+
".s"
)
ztrace_s
:=
filepath
.
Join
(
pkgdir
,
"ztrace"
+
kind
+
".s"
)
if
len
(
tpkg
.
Importv
)
==
0
{
if
len
(
tpkg
.
Importv
)
==
0
{
err
=
removeFile
(
ztrace_s
)
err
=
removeFile
(
ztrace_s
)
}
else
{
}
else
{
...
@@ -875,10 +875,10 @@ func traceExport(tpkg *Package, kind string) []byte {
...
@@ -875,10 +875,10 @@ func traceExport(tpkg *Package, kind string) []byte {
for
_
,
event
:=
range
tpkg
.
Eventv
{
for
_
,
event
:=
range
tpkg
.
Eventv
{
importedEvent
:=
traceImported
{
importedEvent
:=
traceImported
{
traceEvent
:
event
,
traceEvent
:
event
,
ImportSpec
:
&
traceImport
{
PkgName
:
pkgname
,
PkgPath
:
pkgpath
},
ImportSpec
:
&
traceImport
{
PkgName
:
pkgname
,
PkgPath
:
pkgpath
},
ImporterPkg
:
nil
,
// from nowhere
ImporterPkg
:
nil
,
// from nowhere
ImportedAs
:
nil
,
// no naming for imports
ImportedAs
:
nil
,
// no naming for imports
}
}
err
:=
traceEventImportTmpl
.
Execute
(
exported
,
importedEvent
)
err
:=
traceEventImportTmpl
.
Execute
(
exported
,
importedEvent
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -896,7 +896,6 @@ func traceExportHash(tpkg *Package, kind string) string {
...
@@ -896,7 +896,6 @@ func traceExportHash(tpkg *Package, kind string) string {
return
fmt
.
Sprintf
(
"%x"
,
sha1
.
Sum
(
traceExport
(
tpkg
,
kind
)))
return
fmt
.
Sprintf
(
"%x"
,
sha1
.
Sum
(
traceExport
(
tpkg
,
kind
)))
}
}
func
main
()
{
func
main
()
{
log
.
SetFlags
(
0
)
log
.
SetFlags
(
0
)
log
.
SetPrefix
(
"gotrace: "
)
log
.
SetPrefix
(
"gotrace: "
)
...
...
go/xcommon/tracing/tracing.go
View file @
63c2f263
...
@@ -17,15 +17,18 @@
...
@@ -17,15 +17,18 @@
// See COPYING file for full licensing terms.
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// See https://www.nexedi.com/licensing for rationale and options.
// Package tracing provides runtime and usage support for Go tracing facilities
/*
// TODO describe how to define tracepoints
Package tracing provides runtime and usage support for Go tracing facilities
// TODO doc:
// - tracepoints
TODO describe how to define tracepoints
// - probes
TODO doc:
// - probes can be attached/detached to/from tracepoints
- tracepoints
//
- probes
// TODO document //trace:event & //trace:import
- probes can be attached/detached to/from tracepoints
// TODO document `gotrace gen` + `gotrace list`
TODO document //trace:event & //trace:import
TODO document `gotrace gen` + `gotrace list`
*/
package
tracing
package
tracing
import
(
import
(
...
...
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