@@ -29,8 +29,11 @@ const http2spy = require('http2spy');
2929import { Logging , Sink , Log , Entry , TailEntriesResponse } from '../src' ;
3030import * as http from 'http' ;
3131import * as instrumentation from '../src/utils/instrumentation' ;
32-
33- // block all attempts to chat with the metadata server (kokoro runs on GCE)
32+ import { trace } from '@opentelemetry/api' ;
33+ import { Resource } from '@opentelemetry/resources' ;
34+ import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions' ;
35+ import { TraceExporter } from '@google-cloud/opentelemetry-cloud-trace-exporter' ;
36+ import { NodeSDK } from '@opentelemetry/sdk-node' ;
3437nock ( HOST_ADDRESS )
3538 . get ( ( ) => true )
3639 . replyWithError ( { code : 'ENOTFOUND' } )
@@ -270,8 +273,8 @@ describe('Logging', () => {
270273 } ) ;
271274
272275 describe ( 'logs' , ( ) => {
273- function getTestLog ( loggingInstnce = null ) {
274- const log = ( loggingInstnce || logging ) . log ( generateName ( ) ) ;
276+ function getTestLog ( loggingInstance = null ) {
277+ const log = ( loggingInstance || logging ) . log ( generateName ( ) ) ;
275278
276279 const logEntries = [
277280 // string data
@@ -733,15 +736,185 @@ describe('Logging', () => {
733736 } ) ;
734737 } ) ;
735738
739+ describe ( 'logs with open telemetry context' , ( ) => {
740+ let sdk : NodeSDK ;
741+ before ( ( ) => {
742+ // initialize the SDK and register with the OpenTelemetry API
743+ // this enables the API to record telemetry
744+ sdk = new NodeSDK ( {
745+ resource : new Resource ( {
746+ [ SEMRESATTRS_SERVICE_NAME ] : TESTS_PREFIX ,
747+ } ) ,
748+ // Add cloud trace exporter as SDK trace exporter
749+ traceExporter : new TraceExporter ( ) ,
750+ } ) ;
751+ sdk . start ( ) ;
752+ } ) ;
753+
754+ after ( ( ) => {
755+ sdk . shutdown ( ) ;
756+ } ) ;
757+
758+ it ( 'should not overwrite user defined trace and spans with OpenTelemetry context' , done => {
759+ trace . getTracer ( TESTS_PREFIX ) . startActiveSpan ( 'foo' , span => {
760+ const { log} = getTestLog ( ) ;
761+ const spanTestMessage = 'span test log message' ;
762+ const metadata = {
763+ trace : '1' ,
764+ spanId : '1' ,
765+ traceSampled : false ,
766+ } ;
767+ const logEntry = log . entry ( metadata , spanTestMessage ) ;
768+ log . write ( logEntry , err => {
769+ assert . ifError ( err ) ;
770+ getEntriesFromLog ( log , { numExpectedMessages : 1 } , ( err , entries ) => {
771+ assert . ifError ( err ) ;
772+ const entry = entries ! [ 0 ] ;
773+ assert . strictEqual ( entry . data , spanTestMessage ) ;
774+ assert . strictEqual ( entry . metadata . trace , metadata . trace ) ;
775+ assert . strictEqual ( entry . metadata . spanId , metadata . spanId ) ;
776+ assert . strictEqual (
777+ entry . metadata . traceSampled ,
778+ metadata . traceSampled
779+ ) ;
780+ } ) ;
781+ } ) ;
782+ span . end ( ) ;
783+ } ) ;
784+ done ( ) ;
785+ } ) ;
786+
787+ it ( 'should write a log with trace and spans from OpenTelemetry context' , done => {
788+ trace . getTracer ( TESTS_PREFIX ) . startActiveSpan ( 'foo' , span => {
789+ const traceId = span . spanContext ( ) . traceId ;
790+ const spanId = span . spanContext ( ) . spanId ;
791+ const traceSampled = ( span . spanContext ( ) . traceFlags & 1 ) !== 0 ;
792+ const { log} = getTestLog ( ) ;
793+ const spanTestMessage = 'span test log message' ;
794+ const logEntry = log . entry ( spanTestMessage ) ;
795+ log . write ( logEntry , err => {
796+ assert . ifError ( err ) ;
797+ getEntriesFromLog ( log , { numExpectedMessages : 1 } , ( err , entries ) => {
798+ assert . ifError ( err ) ;
799+ const entry = entries ! [ 0 ] ;
800+ assert . strictEqual ( entry . data , spanTestMessage ) ;
801+ assert . strictEqual (
802+ entry . metadata . trace ,
803+ `projects/${ PROJECT_ID } /traces/${ traceId } `
804+ ) ;
805+ assert . strictEqual ( entry . metadata . spanId , spanId ) ;
806+ assert . strictEqual ( entry . metadata . traceSampled , traceSampled ) ;
807+ } ) ;
808+ } ) ;
809+ span . end ( ) ;
810+ } ) ;
811+ done ( ) ;
812+ } ) ;
813+
814+ it ( 'should write a log with OpenTelemetry trace and spans and ignore http requests traceparent header' , done => {
815+ const { log} = getTestLog ( ) ;
816+ const URL = 'http://www.google.com' ;
817+ trace . getTracer ( TESTS_PREFIX ) . startActiveSpan ( 'foo' , span => {
818+ // Use the response of a http request as the incomingmessage request obj.
819+ http . get ( URL , res => {
820+ res . url = URL ;
821+ res . headers = {
822+ traceparent :
823+ '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01' ,
824+ } ;
825+ const metadata = { httpRequest : res } ;
826+ const logEntry = log . entry ( metadata , 'some log message' ) ;
827+
828+ const traceId = span . spanContext ( ) . traceId ;
829+ const spanId = span . spanContext ( ) . spanId ;
830+ const traceSampled = ( span . spanContext ( ) . traceFlags & 1 ) !== 0 ;
831+
832+ log . write ( logEntry , err => {
833+ assert . ifError ( err ) ;
834+ getEntriesFromLog (
835+ log ,
836+ { numExpectedMessages : 1 } ,
837+ ( err , entries ) => {
838+ assert . ifError ( err ) ;
839+ const entry = entries ! [ 0 ] ;
840+ assert . strictEqual ( entry . data , 'some log message' ) ;
841+ assert . strictEqual (
842+ entry . metadata . httpRequest ?. requestUrl ,
843+ URL
844+ ) ;
845+ assert . strictEqual (
846+ entry . metadata . httpRequest ?. protocol ,
847+ 'http:'
848+ ) ;
849+ assert . strictEqual (
850+ entry . metadata . trace ,
851+ `projects/${ PROJECT_ID } /traces/${ traceId } `
852+ ) ;
853+ assert . strictEqual ( entry . metadata . spanId , spanId ) ;
854+ assert . strictEqual ( entry . metadata . traceSampled , traceSampled ) ;
855+ }
856+ ) ;
857+ } ) ;
858+ } ) ;
859+ span . end ( ) ;
860+ } ) ;
861+ done ( ) ;
862+ } ) ;
863+
864+ it ( 'should write a log with OpenTelemetry trace and spans and ignore http requests x-cloud-trace-context header' , done => {
865+ const { log} = getTestLog ( ) ;
866+ const URL = 'http://www.google.com' ;
867+ trace . getTracer ( TESTS_PREFIX ) . startActiveSpan ( 'foo' , span => {
868+ // Use the response of a http request as the incomingmessage request obj.
869+ http . get ( URL , res => {
870+ res . url = URL ;
871+ res . headers = {
872+ 'x-cloud-trace-context' : '1/2;o=1' ,
873+ } ;
874+ const metadata = { httpRequest : res } ;
875+ const logEntry = log . entry ( metadata , 'some log message' ) ;
876+ const traceId = span . spanContext ( ) . traceId ;
877+ const spanId = span . spanContext ( ) . spanId ;
878+ const traceSampled = ( span . spanContext ( ) . traceFlags & 1 ) !== 0 ;
879+ log . write ( logEntry , err => {
880+ assert . ifError ( err ) ;
881+ getEntriesFromLog (
882+ log ,
883+ { numExpectedMessages : 1 } ,
884+ ( err , entries ) => {
885+ assert . ifError ( err ) ;
886+ const entry = entries ! [ 0 ] ;
887+ assert . strictEqual ( entry . data , 'some log message' ) ;
888+ assert . strictEqual (
889+ entry . metadata . httpRequest ?. requestUrl ,
890+ URL
891+ ) ;
892+ assert . strictEqual (
893+ entry . metadata . httpRequest ?. protocol ,
894+ 'http:'
895+ ) ;
896+ assert . strictEqual (
897+ entry . metadata . trace ,
898+ `projects/${ PROJECT_ID } /traces/${ traceId } `
899+ ) ;
900+ assert . strictEqual ( entry . metadata . spanId , spanId ) ;
901+ assert . strictEqual ( entry . metadata . traceSampled , traceSampled ) ;
902+ }
903+ ) ;
904+ } ) ;
905+ } ) ;
906+ span . end ( ) ;
907+ } ) ;
908+ done ( ) ;
909+ } ) ;
910+ } ) ;
911+
736912 it ( 'should set the default resource' , done => {
737913 const { log} = getTestLog ( ) ;
738-
739914 const text = 'entry-text' ;
740915 const entry = log . entry ( text ) ;
741-
742916 log . write ( entry , err => {
743917 assert . ifError ( err ) ;
744-
745918 getEntriesFromLog ( log , { numExpectedMessages : 1 } , ( err , entries ) => {
746919 assert . ifError ( err ) ;
747920 const entry = entries ! [ 0 ] ;
0 commit comments