Background

Our application is a segment of a source code mirroring service. It saves git commits and blobs to Cloud Datastore.
With OpenCensus, we’ll gain insights into how our distributed application is performing by instrumenting our application to examine
traces.

End to end code sample

With all the steps combined, we’ll finally have this code snippet

packagemainimport("context""log""cloud.google.com/go/datastore""contrib.go.opencensus.io/exporter/stackdriver""go.opencensus.io/trace")typerecordstruct{Hashstring`json:"hash"`Messagestring`json:"message"`Datestring`json:"date"`}// record implements Load so that datastore can deserialize to it
func(r*record)Load(ps[]datastore.Property)error{returndatastore.LoadStruct(r,ps)}funcmain(){projectID:="census-demos"client,err:=datastore.NewClient(context.Background(),projectID)iferr!=nil{log.Fatalf("Failed to create datastore client: %v",err)}deferclient.Close()// Warm up datastore first to ensure the session is already setup. Usually in
// your application, you'd have hit this point by the time you are handling traffic.
_,_=client.Count(context.Background(),datastore.NewQuery("Record"))sd,err:=stackdriver.NewExporter(stackdriver.Options{ProjectID:projectID,})iferr!=nil{log.Fatalf("Failed to create the Stackdrsiver exporter: %v",err)}defersd.Flush()// For demo purposes, we'll always sample traces
trace.ApplyConfig(trace.Config{DefaultSampler:trace.AlwaysSample()})trace.RegisterExporter(sd)// Now onto the application code
ctx,span:=trace.StartSpan(context.Background(),"DatastoreOpenCensus-Tutorial")deferspan.End()// Count the number of records
_,nrSpan:=trace.StartSpan(ctx,"Count")q:=datastore.NewQuery("Record")n,err:=client.Count(ctx,q)nrSpan.End()iferr!=nil{log.Fatalf("Failed to count the number of records: %v",err)}ifn==0{log.Printf("No records available yet unfortunately!")}else{log.Printf("There are %d records",n)}// Delete the bad record entities
badRecords:=[]*datastore.Key{datastore.NameKey("Record","6746d075-3b42-4a9b-80d6-4b43b91152ed",nil),datastore.NameKey("Record","af1ed566-0e76-4033-b9a4-bbb8dcf5b15b",nil),}_,dmSpan:=trace.StartSpan(ctx,"DeleteBadRecords")err=client.DeleteMulti(ctx,badRecords)dmSpan.End()iferr!=nil{log.Fatalf("Failed to delete the bad record: %v",err)}// Insert the actual/good records
goodRecords:=[]*record{{Hash:"34b58f87c92fefa14ed717149a0502b29c090d1f",Date:"Thu Oct 26 22:54:05 2017 -0700",Message:"routing: now supporting multiple divergent route/proxies",},{Hash:"8d2d3f365197aea09c9fb6d996453ca6618d17cd",Date:"Wed Oct 25 21:34:45 2017 -0700",Message:"ignore unmarshal errors from ping, avoid nil roundRobinAddress",},}keys:=[]*datastore.Key{datastore.NameKey("Record","6746d075-3b42-4a9b-80d6-4b43b91152ed",nil),datastore.NameKey("Record","af1ed566-0e76-4033-b9a4-bbb8dcf5b15b",nil),}_,pmSpan:=trace.StartSpan(ctx,"PutGoodRecords")_,err=client.PutMulti(ctx,keys,goodRecords)pmSpan.End()iferr!=nil{log.Fatalf("Failed to put good records: %v",err)}// Now fetch all the records
varallRecords[]*record_,gaSpan:=trace.StartSpan(ctx,"FetchAllRecords")allKeys,err:=client.GetAll(ctx,q,&allRecords)gaSpan.End()iferr!=nil{log.Fatalf("Failed to get back all records: %v",err)}fori,key:=rangeallKeys{log.Printf("#%d: Key(%T)=%q Record=%+v\n",i,key,key,allRecords[i])}// Then finally clear them all
_,dmaSpan:=trace.StartSpan(ctx,"DeleteAllRecords")err=client.DeleteMulti(ctx,allKeys)dmaSpan.End()iferr!=nil{log.Fatalf("Failed to delete all records: %v",err)}}