instagraphql

package module
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2024 License: MIT Imports: 13 Imported by: 0

README

Instana instrumentation for graphql

This module contains instrumentation code for the graphql API.

The instrumentation is compatible with graphql v0.8.0. If you need support for newer versions, file an issue on this repository.

GoDoc

Installation

To add the module to your go.mod file run the following command in your project directory:

$ go get github.com/instana/go-sensor/instrumentation/instagraphql

Usage

A complete working example can be found here.

instagraphql offers the following method wrappers able to collect GraphQL query data:

instagraphql.Do usage example
// create an instance of the Instana sensor
sensor := instana.NewSensor("go-graphql")

// setup GraphQL normally
...
schema, err := graphql.NewSchema(schemaConfig)
...

// Create a graphql.Params instance to prepare the query to be processed

query := `query myQuery {
  myfield
}`

params := graphql.Params{Schema: schema, RequestString: query}

// Call instagraphql.Do instead of the original graphql.Do.
// Make sure to provide a valid context (usually an HTTP req.Context()) if any.
r := instagraphql.Do(context.Background(), sensor, params)

fmt.Println("do something with the result", r)
instagraphql.Subscribe usage example
// create an instance of the Instana sensor
sensor := instana.NewSensor("go-graphql")

...

go func() {
  ctx := context.Background()

  subscribeParams := graphql.Params{
    Context:       ctx,
    RequestString: mySubscriptionQuery,
    Schema:        schema,
  }

  instagraphql.Subscribe(ctx, sensor, subscribeParams)
}()
instagraphql.ResultCallbackFn usage example

The instagraphql.ResultCallbackFn depends on the handler.ResultCallbackFn function from the handler API, which provides a convenient HTTP handler, as well as a GraphQL playground and more.

// create an instance of the Instana sensor
sensor := instana.NewSensor("go-graphql")

h := handler.New(&handler.Config{
  Schema:           &schema,
  Pretty:           true,
  GraphiQL:         false,
  Playground:       true,
  // The second argument is your previous provided callback function, or nil if you had none.
  ResultCallbackFn: instagraphql.ResultCallbackFn(sensor, nil),
})

http.Handle("/graphql", h)

if err := http.ListenAndServe("0.0.0.0:9191", nil); err != nil {
  log.Fatal(err)
}

See the instagraphql package documentation for detailed examples.

Documentation

Index

Examples

Constants

View Source
const Version = "1.11.0"

Version is the instrumentation module semantic version

Variables

This section is empty.

Functions

func Do

Do wraps the original graphql.Do, traces the GraphQL query and returns the result of the original graphql.Do

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/graphql-go/graphql"

	instana "github.com/instana/go-sensor"
	"github.com/instana/go-sensor/instrumentation/instagraphql"
)

func main() {
	// create an instance of the Instana sensor
	sensor := instana.NewSensor("go-graphql")

	// setup GraphQL normally
	fields := graphql.Fields{
		"myfield": &graphql.Field{
			Type: graphql.String,
		},
	}

	rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
	schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}

	schema, err := graphql.NewSchema(schemaConfig)

	if err != nil {
		log.Fatalf("failed to create new schema, error: %v", err)
	}

	query := `query myQuery {
		myfield
	}`

	params := graphql.Params{Schema: schema, RequestString: query}

	// Call instagraphql.Do instead of the original graphql.Do.
	// Make sure to provide a valid context (usually an HTTP req.Context()) if any.
	r := instagraphql.Do(context.Background(), sensor, params)

	fmt.Println("do something with the result", r)
}
Output:

func ResultCallbackFn

ResultCallbackFn traces the GraphQL query and executes the original handler.ResultCallbackFn if fn is provided.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"

	"github.com/graphql-go/graphql"
	"github.com/graphql-go/handler"

	instana "github.com/instana/go-sensor"
	"github.com/instana/go-sensor/instrumentation/instagraphql"
)

func main() {
	// create an instance of the Instana sensor
	sensor := instana.NewSensor("go-graphql")

	// setup GraphQL normally
	fields := graphql.Fields{
		"myfield": &graphql.Field{
			Type: graphql.String,
		},
	}

	rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
	schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}

	schema, err := graphql.NewSchema(schemaConfig)

	if err != nil {
		log.Fatalf("failed to create new schema, error: %v", err)
	}

	// Setup the handler

	// The original ResultCallbackFn function if you have one. Otherwise, just pass nil
	var fn handler.ResultCallbackFn = func(ctx context.Context, params *graphql.Params, result *graphql.Result, responseBody []byte) {
		fmt.Println("Original callback function")
	}

	h := handler.New(&handler.Config{
		Schema:   &schema,
		Pretty:   true,
		GraphiQL: true,
		// instagraphql.ResultCallbackFn instruments the code and returns the original function, if any.
		ResultCallbackFn: instagraphql.ResultCallbackFn(sensor, fn),
	})

	http.Handle("/graphql", h)

	if err := http.ListenAndServe("0.0.0.0:9191", nil); err != nil {
		log.Fatal(err)
	}
}
Output:

func Subscribe

func Subscribe(ctx context.Context, sensor instana.TracerLogger, p graphql.Params) chan *graphql.Result

Subscribe wraps the original graphql.Subscribe, traces the GraphQL query and returns the result of the original graphql.Subscribe

Types

type ExpiringMap

type ExpiringMap struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ExpiringMap holds a map of spans that are automatically removed from this map after the provided duration expires. The expiration time is renewed if the map is set with the same key before the original time exipres.

func (*ExpiringMap) Get

func (em *ExpiringMap) Get(k string) ot.Span

Get returns the span for the given k or nil if not found.

func (*ExpiringMap) Set

func (em *ExpiringMap) Set(k string, v ot.Span, d time.Duration)

Set will set the span which will expire after d is reached. If a span is set with the same key before the original one expires, the time will be renewed.

Jump to

Keyboard shortcuts

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