Giter VIP home page Giter VIP logo

opentracing's Introduction

OpenTracing for Haskell

Build Status

OpenTracing is an attempt to define a common API to instrument code for Dapper-style distributed tracing, abstracting over various implementations of this concept (such as Twitter's Zipkin, Uber's Jaeger, or even Apache HTrace.

opentracing's People

Contributors

adetokunbo avatar alexbiehl avatar benweitzman avatar dfithian avatar isovector avatar jship avatar kim avatar peterbecich avatar philderbeast avatar zliu41 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

opentracing's Issues

Unable to get zipkin metrics out

Hi there, I'm attempting to send instrumentation out to zipkin.

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Monad.IO.Class
import Control.Monad
import Control.Concurrent
import           OpenTracing
import qualified OpenTracing as OT
import qualified OpenTracing.Log as OT
import qualified OpenTracing.Zipkin as Z
import qualified OpenTracing.Zipkin.HttpReporter as ZR

zipkinTracing :: MonadIO m => OT.Sampler -> m (OT.Tracing Z.ZipkinContext MonadIO)
zipkinTracing sampler = do
  let endpoint = ZR.Endpoint (Just "myservice") (Just $ read "localhost") Nothing (Just 9411)
  env <- Z.newEnv sampler
  renv <- liftIO $ ZR.newEnv ZR.V2 endpoint "localhost" 9411 OT.jsonMap
  pure $ OT.Tracing (Z.zipkinTracer env) (ZR.zipkinHttpReporter renv)

main :: IO ()
main = do
  tracing <- zipkinTracing $ constSampler True
  forM_ [0..1000] . const $ traced' tracing (spanOpts "hello" mempty) $ \x -> putStrLn "hello" >> threadDelay 500000

I started zipkin via the quickstart guide:

wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'
java -jar zipkin.jar

and it is running on localhost:9411.

Any suggestions for how to continue? Thanks!

Bump base minimum constraint to 4.12?

I tried 1e130d0 with low versions of GHC to find the minimum version I could compile with and that was ghc-8.6.1. I had this problem compiling with ghc-8.4.4:

$ cabal build all --enable-tests --enable-benchmarks
Resolving dependencies...
Build profile: -w ghc-8.4.4 -O1
...
Data/Vinyl/ARec/Internal.hs:159:3: error:
    • Illegal polymorphic type:
        forall s. Int -> SmallMutableArray s -> ST s ()
      Perhaps you intended to use RankNTypes or Rank2Types
    • In the definition of data constructor ‘ARecBuilder’
      In the newtype declaration for ‘ARecBuilder’
    |
159 |   ARecBuilder ( forall s.
    |   ^^^^^^^^^^^^^^^^^^^^^^^...
Error: cabal: Failed to build vinyl-0.14.3 (which is required by
exe:opentracing-example-simple from opentracing-examples-0.2.0 and
exe:opentracing-example-rpc from opentracing-examples-0.2.0). See the build
log above for details.

Should we bump the base minimum constraint like this?

-    , base  >= 4.9 && < 4.17
+    , base  >= 4.12 && < 4.17

Same story for 64fd065, the commit hash for the 0.2.2 tag.

Hackage release

Is there a roadmap for a Hackage release?

I’m using this library in another library I’m developing that integrates polysemy’s free monad architecture with distributed tracing.

I’d love to help out in any way that I can to get this ready for release. It’s a really great project that I think a lot of people will benefit from!

Release 0.2.3 to hackage?

Hi!

I'm a happy user of your library (thanks!) who'd like to migrate to GHC 9.4 and 9.6.
Are you planning releasing the current master to Hackage in the near future? :)

Thanks!

stdTracer thread safety

The stdTracer in OpenTracing.Standard is built using a StdEnv, and the envPRNG field in StdEnv is a GenIO.

GenIO isn't thread-safe unfortunately: https://hackage.haskell.org/package/mwc-random-0.14.0.0/docs/System-Random-MWC.html#t:Gen

We noticed issues in tests that concurrently start up traces using the same Tracer where the resulting finished spans would occasionally have incorrect parent/child references due to the IDs being duplicated.

SimSpace has made the GenIO access thread-safe in this commit - https://github.com/Simspace/opentracing/commit/43ba8fd415562281e087d1d7a5b300bbd9d9837a - and our tests are working great. We're happy to upstream this fix as well.

Setting top-level "kind" JSON key in Zipkin implementation fails

This line adds a "kind": "foo" key to the JSON blob which is sent to Zipkin:

Curling these payloads to zipkin directly shows the issue:

$ curl -X POST --header 'content-type: application/json' --url 'http://localhost:9411/api/v2/spans' --data '[{"name":"apikinesisworkflowevents","parentId":"669d318a1f17eca2","id":"669d318a1f17eca1","traceId":"8ddd20a39da03fb1a7a7ddffe46f8747", \
    "kind":"server",\
    "timestamp":1509566690478713,"duration":101327,"debug":false,"localEndpoint":{"serviceName":"apollo","ipv4":"127.0.0.1","port":9411},"annotations":[]}]'
Cannot decode spans

$ curl -X POST --header 'content-type: application/json' --url 'http://localhost:9411/api/v2/spans' --data '[{"name":"apikinesisworkflowevents","parentId":"669d318a1f17eca2","id":"669d318a1f17eca1","traceId":"8ddd20a39da03fb1a7a7ddffe46f8747", \
    "timestamp":1509566690478713,"duration":101327,"debug":false,"localEndpoint":{"serviceName":"apollo","ipv4":"127.0.0.1","port":9411},"annotations":[]}]'

where the only difference is the presence of the server key.

License?

Hey I'm in the middle of trying to get opentracing (using Jaeger) working with a small Servant based API I'm writing.

I'd like to use your library, but am not sure what the license is, would you mind setting one on the repository?

Can't create a Tracer type

I'm trying to get the WAI integration working, and I'm almost there but I can't create the last bit I need, a Tracer value.

I have the functions I want the tracer to run, but due to the type variable on tracer's definition (I think), haskell gets confused about which type to use. Even when I specialize to IO (instead of using a forall m. MonadIO m), I get this type error:

src/Tracing/TracingBackend.hs:91:118-124: error: …                                                                                                                                                                                                                                
    • Couldn't match type ‘m’ with ‘IO’                                                                                                                                                                                                                                           
      ‘m’ is a rigid type variable bound by                                                                                                                                                                                                                                       
        a type expected by the context:                                                                                                                                                                                                                                           
          forall (m :: * -> *). MonadIO m => SpanOpts -> m Span                                                                                                                                                                                                                   
        at /path/to/src/Tracing/TracingBackend.hs:91:97                                                                                                                                                                              
      Expected type: SpanOpts -> m Span                                                                                                                                                                                                                                           
        Actual type: SpanOpts -> IO Span                                                                                                                                                                                                                                          
    • In the ‘tracerStart’ field of a record                                                                                                                                                                                                                                      
      In the first argument of ‘return’, namely                                                                                                                                                                                                                                   
        ‘(tracer                                                                                                                                                                                                                                                                  
            {tracerStart = startFn, tracerReport = jaegerAgentReporter j})’                                                                                                                                                                                                       
      In the expression:                                                                                                                                                                                                                                                          
        return                                                                                                                                                                                                                                                                    
          (tracer                                                                                                                                                                                                                                                                 
             {tracerStart = startFn, tracerReport = jaegerAgentReporter j}) 

Here's what the code looks like:

class Tracing T
    -- ... other code ... 
    traceApplication :: t -> Application -> IO Application

instance Tracing TracingBackend where
    -- ... other code ... 
    -- TODO: check to ensure that app wide tracing is enabled                                                                                                                                                                                                                     
    traceApplication t app = if appWideTracingEnabled then instrumentApp app else pure app
        where
          jaegerOptions = tracingSettings t
          appWideTracingEnabled = tracingAppWide $ tracingCfg t
          sampling = probSampler $ tracingSamplingRate $ tracingCfg t
          propagation = jaegerPropagation

          defaultReporter :: FinishedSpan -> IO ()
          defaultReporter = makeLoggerReporter t

          -- Create Standard ENV for Tracer to use, create standard tracer from the env                                                                                                                                                                                           
          mkTracer :: IO (SpanOpts -> IO Span)
          mkTracer = newStdEnv sampling >>= pure . stdTracer

          -- Update Tracer with a JaegerAgentReporter (instead of log based one), produce the middleware                                                                                                                                                                          
          augmentTracerWithJaeger :: Tracer -> (SpanOpts -> IO Span) -> IO Tracer
          augmentTracerWithJaeger tracer startFn = withJaegerAgent jaegerOptions (\j -> return (tracer { tracerStart=startFn
                                                                                                       , tracerReport=jaegerAgentReporter j
                                                                                                       }))

          -- Use the created tracer to make the middleware                                                                                                                                                                                                                        
          makeMiddleware :: Application -> Tracer -> IO Application
          makeMiddleware app tracer = pure (opentracing tracer propagation (\activeSpan -> app))

          -- Instrument an actual application with the agent reporter                                                                                                                                                                                                             
          instrumentApp :: Application -> IO Application
          instrumentApp app = liftIO (logMsg t INFO "Instrumenting application...")
                              >> mkTracer
                              >>= augmentTracerWithJaeger (Tracer undefined undefined)
                              >>= makeMiddleware app
                              >>= pure

To me it seems like haskell is expecting the IO to be an m (as bound by tracer's definition), and cannot get over the requirement.

I've tried setting ScopedTypeVariables (and abstracting the MonadIO m type in the typeclass code too), but it still won't convince Haskell that both ms are the same, I just get the same error with m1 vs m instead of m and IO.

I've looked at Backends.hs and I'm honestly not sure how it works when you're in the IO monad yet manage to create a Tracer properly.

ZipKin V2 error with jaeger-all-in-one

With your recommendation in #16, I started trying out using the zipkin v2 HttpReporter with the jaeger all-in-one docker container. Things seem to work fairly well but every now and then I'm getting:

Unable to process request body: validation failure list:
parentId in body should be at least 16 chars long

Heres the payload its generating:

[{"name":"range-server response ","id":"864aec327fbcb730","traceId":"18ceef753bb8676f2acbb26ea606b7f","parentId":"d89caaa049427f8","timestamp":1529711969086253,"duration":8,"debug":false,"localEndpoint":{"serviceName":"portal-server","ipv4":"127.0.0.1"},"annotations":[],"tags":{}}]

The parentId looks like its 15 characters, but it appears to be validating for 16.

Jaeger Agent fails to parse emitBatch compact thrift message sent over UDP from JaegerAgentReporter

So after getting opentracing-wai working and sending data over UDP to a Jaeger agent, I found that the emitBatch commands that are being sent aren't being properly parsed by Jaeger...

Here's waht the data looks like, and the error:

*jaeger.AgentEmitBatchArgs field 0 read error: EOF

This is in the Process function of jaeger/agent.go in the jaeger codebase (I built it locally from source to do some print-debugging.

I know the this library is still in the early stages, but is this a known bug? Has UDP to Jaeger over Thrift compact protocol worked yet?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.