/* Wraps the RoundTrip function of the given RoundTripper. Will provide accounting metrics for the http.Request / http.Response life-cycle Callers of RoundTrip are responsible for setting the ‘X-CF-RequestID’ field in the request header if they have one. Callers are also responsible for setting the ‘X-CF-ApplicationID’ and ‘X-CF-InstanceIndex’ fields in the request header if they are known. */ func (irt *instrumentedRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { requestId, err := GenerateUuid() if err != nil { log.Printf("failed to generated request ID: %v\n", err) requestId = &uuid.UUID{} } startTime := time.Now() parentRequestId := req.Header.Get("X-CF-RequestID") req.Header.Set("X-CF-RequestID", requestId.String()) resp, roundTripErr := irt.roundTripper.RoundTrip(req) var statusCode int var contentLength int64 if roundTripErr == nil { statusCode = resp.StatusCode contentLength = resp.ContentLength } httpStartStop := factories.NewHttpStartStop(req, statusCode, contentLength, events.PeerType_Client, requestId) if parentRequestId != "" { if id, err := uuid.ParseHex(parentRequestId); err == nil { httpStartStop.ParentRequestId = factories.NewUUID(id) } } httpStartStop.StartTimestamp = proto.Int64(startTime.UnixNano()) err = irt.emitter.Emit(httpStartStop) if err != nil { log.Printf("failed to emit startstop event: %v\n", err) } return resp, roundTripErr }
/* Wraps the given http.Handler ServerHTTP function Will provide accounting metrics for the http.Request / http.Response life-cycle */ func (ih *instrumentedHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { requestId, err := uuid.ParseHex(req.Header.Get("X-Vcap-Request-Id")) if err != nil { requestId, err = GenerateUuid() if err != nil { log.Printf("failed to generated request ID: %v\n", err) requestId = &uuid.UUID{} } req.Header.Set("X-Vcap-Request-Id", requestId.String()) } rw.Header().Set("X-Vcap-Request-Id", requestId.String()) startTime := time.Now() instrumentedWriter := &instrumentedResponseWriter{writer: rw, statusCode: 200} ih.handler.ServeHTTP(instrumentedWriter, req) startStopEvent := factories.NewHttpStartStop(req, instrumentedWriter.statusCode, instrumentedWriter.contentLength, events.PeerType_Server, requestId) startStopEvent.StartTimestamp = proto.Int64(startTime.UnixNano()) err = ih.emitter.Emit(startStopEvent) if err != nil { log.Printf("failed to emit startstop event: %v\n", err) } }
func createEnvelope(eventType events.Envelope_EventType) *events.Envelope { envelope := &events.Envelope{Origin: proto.String("origin"), EventType: &eventType, Timestamp: proto.Int64(time.Now().UnixNano())} switch eventType { case events.Envelope_HttpStartStop: req, _ := http.NewRequest("GET", "http://www.example.com", nil) req.RemoteAddr = "www.example.com" req.Header.Add("User-Agent", "user-agent") uuid, _ := uuid.NewV4() envelope.HttpStartStop = factories.NewHttpStartStop(req, http.StatusOK, 128, events.PeerType_Client, uuid) case events.Envelope_ValueMetric: envelope.ValueMetric = factories.NewValueMetric("some-value-metric", 123, "km") case events.Envelope_CounterEvent: envelope.CounterEvent = factories.NewCounterEvent("some-counter-event", 123) case events.Envelope_LogMessage: envelope.LogMessage = factories.NewLogMessage(events.LogMessage_OUT, "some message", "appId", "source") case events.Envelope_ContainerMetric: envelope.ContainerMetric = factories.NewContainerMetric("appID", 123, 1, 5, 5) case events.Envelope_Error: envelope.Error = factories.NewError("source", 123, "message") default: panic(fmt.Sprintf("Unknown event %v\n", eventType)) } return envelope }
/* RoundTrip wraps the RoundTrip function of the given RoundTripper. Will provide accounting metrics for the http.Request / http.Response life-cycle Callers of RoundTrip are responsible for setting the ‘X-Vcap-Request-Id’ field in the request header if they have one. Callers are also responsible for setting the ‘X-CF-ApplicationID’ and ‘X-CF-InstanceIndex’ fields in the request header if they are known. */ func (irt *instrumentedRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { startTime := time.Now() requestId := req.Header.Get("X-Vcap-Request-Id") if requestId == "" { requestIdGuid, err := uuid.NewV4() if err != nil { return nil, err } requestId = requestIdGuid.String() } req.Header.Set("X-Vcap-Request-Id", requestId) resp, roundTripErr := irt.roundTripper.RoundTrip(req) var statusCode int var contentLength int64 if roundTripErr == nil { statusCode = resp.StatusCode contentLength = resp.ContentLength } id, err := uuid.ParseHex(requestId) if err != nil { return nil, err } httpStartStop := factories.NewHttpStartStop(req, statusCode, contentLength, events.PeerType_Client, id) httpStartStop.StartTimestamp = proto.Int64(startTime.UnixNano()) err = irt.emitter.Emit(httpStartStop) if err != nil { log.Printf("failed to emit startstop event: %v\n", err) } return resp, roundTripErr }