xray

package module
v0.0.0-...-2ad47e2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2021 License: Apache-2.0 Imports: 5 Imported by: 0

README

xray - look through your golang objects

Build workflow GoDoc Go Report Card

Introduction

Trouble shooting a project isn't easy, especially when pointers are being used. It's often difficult to get an idea on an object in runtime. Xray is designed to parse runtime objects, and help user to analyze the objects. The accompany dot package, as an example, will generate a dot representation of the object so user could easilly visualize the object.

Examples

Default formatted printer

Typically, user could print their objects in string format:

package main

import "fmt"

type test struct {
	ptr *string
	arr []int
	m   map[string]int
}

func main() {
	str := "deadbeef"
	object := test{
		ptr: &str,
		arr: []int{1, 2, 3},
		m:   map[string]int{"foo": 1, "bar": 2},
	}
	fmt.Printf("object:\n%#v\n", object)
}

Then this is what you got:

object:
main.test{ptr:(*string)(0xc000010200), arr:[]int{1, 2, 3}, m:map[string]int{"bar":2, "foo":1}}

It's not helpful when you want to reason about the pointers, and becomes messy when the struct becomes complicated.

Xray parsed object

By using xray, you can parse the golang object and generate a dot representation of it, here's the snipple:

package main

import (
	"fmt"
	"github.com/hanlins/xray"
	"github.com/hanlins/xray/dot"
)

type test struct {
	ptr *string
	arr []int
	m   map[string]int
}

func main() {
	str := "deadbeef"
	object := test{
		ptr: &str,
		arr: []int{1, 2, 3},
		m:   map[string]int{"foo": 1, "bar": 2},
	}

	s := xray.NewScanner(nil)
	nodeCh := s.Scan(object)
	g, _ := dot.Draw(dot.NewGraphInfo(s), nodeCh, nil)
	fmt.Printf("dot object:\n%s\n", g)
}

You can use the dot binary (need to install graphviz package) locally or some online generator (e.g. viz-js) to generate an image, and use it in your report. Here's the generated image: Alt text

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Node

type Node struct {

	// Children is the set of children nodes of the golang object
	Children map[NodeID]*Node

	// Fields is for structed object, field name will be mapped to a node ID
	Fields map[string]NodeID

	// Array is for array object, retains the order information for children
	Array []NodeID
	// contains filtered or unexported fields
}

Node stores the information for a specific golang object

func NewNode

func NewNode(value reflect.Value) *Node

NewNode initiates a new node for a given golang object

func (*Node) InferPtr

func (n *Node) InferPtr() reflect.Value

InferPtr returns the object being pointed by this pointer node will panic if the node is not a pointer

func (*Node) Kind

func (n *Node) Kind() reflect.Kind

Kind returns the kind of the current node

func (*Node) NodeID

func (n *Node) NodeID(typeIDGen func(reflect.Type) string) NodeID

NodeID derives the NodeID for a given node

func (*Node) RegisterChild

func (n *Node) RegisterChild(node *Node, typeIDGen func(reflect.Type) string) bool

RegisterChild returns true if successfully register child node return false if the child has already been registered

func (*Node) ResolveObj

func (n *Node) ResolveObj() interface{}

ResolveObj returns the reference of the original object

func (*Node) Value

func (n *Node) Value() reflect.Value

Value returns the value of the current node

type NodeID

type NodeID struct {
	// contains filtered or unexported fields
}

NodeID is used to uniquely identify a node

func (*NodeID) Hash

func (nid *NodeID) Hash() string

Hash returns the hash version of NodeID identifier It supposed to be unique among for each node ID

func (*NodeID) IsNil

func (nid *NodeID) IsNil() bool

IsNil returns true if the node ID is for a nil object

func (*NodeID) IsPrimitive

func (nid *NodeID) IsPrimitive() bool

IsPrimitive returns true if the id is of a primitive type

func (*NodeID) Kind

func (nid *NodeID) Kind() reflect.Kind

Kind is used to return the kind of the node

func (*NodeID) String

func (nid *NodeID) String() string

String returns the string representation of NodeID identifier

func (*NodeID) Type

func (nid *NodeID) Type() string

Type is used to return the human readable name of the type Assuming Node value is not nil for this ID

type Scanner

type Scanner struct {
	// contains filtered or unexported fields
}

Scanner stores the global object scan results

func NewScanner

func NewScanner(ctx context.Context) *Scanner

NewScanner instantiates a default Scanner instance

func (*Scanner) Maps

func (s *Scanner) Maps() map[NodeID]map[NodeID]NodeID

Maps returns the scanned KV pairs stored for maps maintained by the scanner

func (*Scanner) Node

func (s *Scanner) Node(id NodeID) *Node

Node returns the Node object based on ID

func (*Scanner) Nodes

func (s *Scanner) Nodes() map[NodeID]*Node

Nodes returns the scanned nodes map maintained by the scanner

func (*Scanner) Scan

func (s *Scanner) Scan(objs ...interface{}) <-chan NodeID

Scan starts the object decomposition process. It's a non-blocking operation. It will return a channel of node IDs and consumer can listen on the channel. When all nodes are sent over the channel, it will be closed.

func (*Scanner) WithFilter

func (s *Scanner) WithFilter(filter func(*Node) bool) *Scanner

WithFilter appends a filter for Node filtering User should NOT modify the object, and it's user's concern to keep the objects untouched.

func (*Scanner) WithParallism

func (s *Scanner) WithParallism(p int) *Scanner

WithParallism configures the number of goroutines running in parallel effectively it's controlling the channel buffer size by default it's processed in serial

func (*Scanner) WithTerminal

func (s *Scanner) WithTerminal(terminal func(*Node) bool) *Scanner

WithTerminal appends a terminal for Node termination checking User should NOT modify the object, and it's user's concern to keep the objects untouched.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL