Exemplo n.º 1
0
 public InstrumentRequestCallback(IConfigAccessor configAccessor, ITracingContext tracingContext,
                                  IEntrySegmentContextAccessor contextAccessor)
 {
     _config          = configAccessor.Get <InstrumentConfig>();
     _tracingContext  = tracingContext;
     _contextAccessor = contextAccessor;
 }
Exemplo n.º 2
0
        public static int Main(string[] args)
        {
            try {
                if (args[0] == "instrument")
                {
                    var config = new InstrumentConfig(args[1]);

                    //so it exists regardless and is deleted
                    File.WriteAllText(KNOWNS_FILENAME, string.Empty);
                    File.WriteAllText(config.HitsPath, string.Empty);

                    //used to track the line index of the instrumented instruction in the knowns file
                    var instrumentIndex = 0;

                    using (var writer = new StreamWriter(KNOWNS_FILENAME, true)) {
                        foreach (var assemblyPath in config.AssemblyPaths)
                        {
                            Instrument(assemblyPath, config, writer, ref instrumentIndex);
                        }
                    }

                    return(0);
                }
                else if (args[0] == "check")
                {
                    return(Check());
                }

                Console.Error.WriteLine("need 'instrument' or 'check' command");
            } catch (Exception e) {
                Console.Error.WriteLine(e);
            }

            return(2);
        }
Exemplo n.º 3
0
        public static int Main(string[] args)
        {
            try {
                if (args[0] == "instrument") {
                    var config = new InstrumentConfig(args[1]);

                    //so it exists regardless and is deleted
                    File.WriteAllText(KNOWNS_FILENAME, string.Empty);
                    File.WriteAllText(config.HitsPath, string.Empty);

                    //used to track the line index of the instrumented instruction in the knowns file
                    var instrumentIndex = 0;

                    using (var writer = new StreamWriter(KNOWNS_FILENAME, true)) {
                        foreach (var assemblyPath in config.AssemblyPaths)
                            Instrument(assemblyPath, config, writer, ref instrumentIndex);
                    }

                    return 0;
                } else if (args[0] == "check")
                    return Check();

                Console.Error.WriteLine("need 'instrument' or 'check' command");
            } catch (Exception e) {
                Console.Error.WriteLine(e);
            }

            return 2;
        }
Exemplo n.º 4
0
        public static int Main(string[] args)
        {
            try {
                if (args[0] == "instrument") {
                    var config = new InstrumentConfig(args[1]);

                    //delete existing hit files generatig during program exercising
                    foreach (var hitsPath in Directory.GetFiles(Directory.GetCurrentDirectory(), HITS_FILENAME_PREFIX + "*")) {
                        File.Delete(hitsPath);
                    }

                    //used to track the line index of the instrumented instruction in the knowns file
                    var instrumentIndex = 0;

                    using (var writer = new StreamWriter(KNOWNS_FILENAME)) {//overwrites
                        foreach (var assemblyPath in config.AssemblyPaths) {
                            Instrument(assemblyPath, config, writer, ref instrumentIndex);
                        }
                    }

                    return 0;
                }
                else if (args[0] == "check") {
                    return Check();
                }

                Console.Error.WriteLine("need 'instrument' or 'check' command");
            }
            catch (Exception e) {
                Console.Error.WriteLine(e);
            }

            return 2;
        }
Exemplo n.º 5
0
 public ServiceDiscoveryV5Service(IConfigAccessor configAccessor, ISkyApmClientV5 skyApmClient,
                                  IRuntimeEnvironment runtimeEnvironment, ILoggerFactory loggerFactory)
     : base(runtimeEnvironment, loggerFactory)
 {
     _config           = configAccessor.Get <InstrumentConfig>();
     _transportConfig  = configAccessor.Get <TransportConfig>();
     this.skyApmClient = skyApmClient;
 }
Exemplo n.º 6
0
 public RegisterService(IConfigAccessor configAccessor, IServiceRegister serviceRegister,
                        IRuntimeEnvironment runtimeEnvironment, ILoggerFactory loggerFactory) : base(runtimeEnvironment,
                                                                                                     loggerFactory)
 {
     _serviceRegister = serviceRegister;
     _config          = configAccessor.Get <InstrumentConfig>();
     _transportConfig = configAccessor.Get <TransportConfig>();
 }
Exemplo n.º 7
0
 public CLRStatsReporter(ConnectionManager connectionManager, ILoggerFactory loggerFactory,
                         IConfigAccessor configAccessor, IRuntimeEnvironment runtimeEnvironment)
 {
     _connectionManager  = connectionManager;
     _logger             = loggerFactory.CreateLogger(typeof(CLRStatsReporter));
     _config             = configAccessor.Get <GrpcConfig>();
     _runtimeEnvironment = runtimeEnvironment;
     _instrumentConfig   = configAccessor.Get <InstrumentConfig>();
 }
Exemplo n.º 8
0
 public PingService(IConfigAccessor configAccessor, IPingCaller pingCaller,
                    IRuntimeEnvironment runtimeEnvironment,
                    ILoggerFactory loggerFactory) : base(
         runtimeEnvironment, loggerFactory)
 {
     _pingCaller       = pingCaller;
     _transportConfig  = configAccessor.Get <TransportConfig>();
     _instrumentConfig = configAccessor.Get <InstrumentConfig>();
 }
        public async Task <IEnumerable <InstrumentResponseDto> > GetInstrumentsAsync(InstrumentConfig configuration, CancellationToken cancellationToken)
        {
            var apiInstance = new MarketDataApi(Org.OpenAPITools.Client.Configuration.Default);
            var currency    = configuration.Currency.ToString().ToUpper(); // string | The currency symbol
            var kind        = configuration.Kind.ToString().ToLower();     // string | Instrument kind, if not provided instruments of all kinds are considered (optional)
            var expired     = configuration.Expired;                       // bool? | Set to true to show expired instruments instead of active ones. (optional)  (default to false)
            var result      = await apiInstance.PublicGetInstrumentsGetAsync(currency, kind, expired) as JObject;

            return(result.ToObject <JsonRpcEnvelopeDto <InstrumentResponseDto[]> >().result);
        }
Exemplo n.º 10
0
 public SegmentContextFactory(IRuntimeEnvironment runtimeEnvironment,
                              ISamplerChainBuilder samplerChainBuilder,
                              IUniqueIdGenerator uniqueIdGenerator,
                              IEntrySegmentContextAccessor entrySegmentContextAccessor,
                              ILocalSegmentContextAccessor localSegmentContextAccessor,
                              IExitSegmentContextAccessor exitSegmentContextAccessor,
                              IConfigAccessor configAccessor)
 {
     _runtimeEnvironment          = runtimeEnvironment;
     _samplerChainBuilder         = samplerChainBuilder;
     _uniqueIdGenerator           = uniqueIdGenerator;
     _entrySegmentContextAccessor = entrySegmentContextAccessor;
     _localSegmentContextAccessor = localSegmentContextAccessor;
     _exitSegmentContextAccessor  = exitSegmentContextAccessor;
     _instrumentConfig            = configAccessor.Get <InstrumentConfig>();
 }
Exemplo n.º 11
0
        private static void Instrument(string assemblyPath, InstrumentConfig config, TextWriter writer, ref int instrumentIndex)
        {
            //Mono.Cecil.[Mdb|Pdb].dll must be alongsize this exe to include sequence points from ReadSymbols
            var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters {
                ReadSymbols = true
            });
            var countReference = assembly.MainModule.ImportReference(countMethodInfo);

            foreach (var type in assembly.MainModule.GetTypes())//.Types doesnt include nested types
            {
                Instrument(type, countReference, config, writer, ref instrumentIndex);
            }

            // FIXME: I have a feeling that this is causing issues, as I don't think we need to write to the assembly anymore?
            //        Disabling the following line doesn't throw errors anymore, so let's see if we can get coverage working now..
            //assembly.Write(assemblyPath, new WriterParameters { WriteSymbols = true });

            var counterPath = typeof(Counter).Assembly.Location;

            File.Copy(counterPath, Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileName(counterPath)), true);
        }
Exemplo n.º 12
0
        private static void Instrument(string assemblyPath, InstrumentConfig config, TextWriter writer, ref int instrumentIndex)
        {
            //Mono.Cecil.[Mdb|Pdb].dll must be alongsize this exe to include sequence points from ReadSymbols
            var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters {
                ReadSymbols = true
            });
            var countReference = assembly.MainModule.Import(countMethodInfo);

            foreach (var type in assembly.MainModule.GetTypes())//.Types doesnt include nested types
            {
                Instrument(type, countReference, config, writer, ref instrumentIndex);
            }

            assembly.Write(assemblyPath, new WriterParameters {
                WriteSymbols = true
            });

            var counterPath = typeof(Counter).Assembly.Location;

            File.Copy(counterPath, Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileName(counterPath)), true);
        }
Exemplo n.º 13
0
        private static void Instrument(
            TypeDefinition type,
            MethodReference countReference,
            InstrumentConfig config,
            TextWriter writer,
            ref int instrumentIndex)
        {
            if (type.FullName == "<Module>")
            {
                return;
            }

            if (!Regex.IsMatch(type.FullName, config.TypeInclude) || Regex.IsMatch(type.FullName, config.TypeExclude))
            {
                return;
            }

            foreach (var method in type.Methods.Where(m => m.HasBody))
            {
                Instrument(method, countReference, config, writer, ref instrumentIndex);
            }
        }
 public Task <IEnumerable <InstrumentResponseDto> > GetInstrumentsAsync(InstrumentConfig configuration, CancellationToken cancellationToken)
 {
     this.logger.LogDebug("Fetch instrument Currency '{0}' and Kind '{1}'", configuration.Currency, configuration.Kind);
     try
     {
         cancellationToken.ThrowIfCancellationRequested();
         var task = decorated.GetInstrumentsAsync(configuration, cancellationToken);
         task.ConfigureAwait(true);
         return(task);
     }
     catch (ApiException ex)
     {
         this.logger.LogError("Exception when calling MarketDataApi.PublicGetInstrumentsGet: " + ex.Message);
         this.logger.LogDebug("Status Code: " + ex.ErrorCode);
         this.logger.LogDebug(ex.StackTrace);
         throw ex;
     }
     catch (Exception exception)
     {
         this.logger.LogError(exception, "En error occured while executing http request");
         throw exception;
     }
 }
Exemplo n.º 15
0
        public static int Main(string[] args)
        {
            try {
                if (args[0] == "instrument")
                {
                    var config = new InstrumentConfig(args[1]);

                    //delete existing hit files generatig during program exercising
                    foreach (var hitsPath in Directory.GetFiles(Directory.GetCurrentDirectory(), HITS_FILENAME_PREFIX + "*"))
                    {
                        File.Delete(hitsPath);
                    }

                    //used to track the line index of the instrumented instruction in the knowns file
                    var instrumentIndex = 0;

                    using (var writer = new StreamWriter(KNOWNS_FILENAME)) {//overwrites
                        foreach (var assemblyPath in config.AssemblyPaths)
                        {
                            Instrument(assemblyPath, config, writer, ref instrumentIndex);
                        }
                    }

                    return(0);
                }
                else if (args[0] == "check")
                {
                    return(Check());
                }

                Console.Error.WriteLine("need 'instrument' or 'check' command");
            } catch (Exception e) {
                Console.Error.WriteLine(e);
            }

            return(2);
        }
Exemplo n.º 16
0
        private static void Instrument(
            MethodDefinition method,
            MethodReference countReference,
            InstrumentConfig config,
            TextWriter writer,
            ref int instrumentIndex)
        {
            if (!Regex.IsMatch(method.FullName, config.MethodInclude) || Regex.IsMatch(method.FullName, config.MethodExclude))
            {
                return;
            }

            var worker = method.Body.GetILProcessor();

            method.Body.SimplifyMacros();

            string lastLine = null;//the sequence point for instructions that dont have one is the last set (if one exists)

            //need to copy instruction list since we modify using worker inserts
            foreach (var instruction in new List <Instruction>(method.Body.Instructions).OrderBy(i => i.Offset))
            {
                var sequencePoint = method.DebugInformation.GetSequencePoint(instruction);
                if (sequencePoint != null)
                {
                    var line = File.ReadLines(sequencePoint.Document.Url).ElementAtOrDefault(sequencePoint.StartLine - 1);
                    if (line != null)
                    {
                        lastLine = line;
                    }
                }

                Instrument(instruction, countReference, method, worker, lastLine, config, writer, ref instrumentIndex);
            }

            method.Body.OptimizeMacros();
        }
Exemplo n.º 17
0
        public async Task <IEnumerable <InstrumentResponseDto> > GetInstrumentsAsync(InstrumentConfig configuration, CancellationToken cancellationToken)
        {
            HttpResponseMessage response = null;

            using (var client = httpClientFactory.CreateClient())
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                response = await client.GetAsync($"{this.Url}get_instruments?currency={configuration.Currency}&kind={configuration.Kind}&expired={configuration.Expired}");
            }
            if (response == null)
            {
                throw new Exception("An unknown error occurred while executing the query");
            }
            cancellationToken.ThrowIfCancellationRequested();
            if (!response.IsSuccessStatusCode)
            {
                return(Enumerable.Empty <InstrumentResponseDto>());
                // throw new Exception($"{response.StatusCode}: {response.ReasonPhrase}");
            }
            var contentStr = await response.Content.ReadAsStringAsync();

            cancellationToken.ThrowIfCancellationRequested();
            return(JsonConvert.DeserializeObject <JsonRpcEnvelopeDto <InstrumentResponseDto[]> >(contentStr)?.result ?? Enumerable.Empty <InstrumentResponseDto>());
        }
Exemplo n.º 18
0
 public UniqueIdGenerator(IConfigAccessor configAccessor)
 {
     _instrumentConfig = configAccessor.Get <InstrumentConfig>();
     _instanceIdentity = GetMD5(_instrumentConfig.ServiceInstanceName);
 }
Exemplo n.º 19
0
        private static void Instrument(Instruction instruction,
                                       MethodReference countReference,
                                       MethodDefinition method,
                                       ILProcessor worker,
                                       string lastLine,
                                       InstrumentConfig config,
                                       TextWriter writer,
                                       ref int instrumentIndex)
        {
            //if the previous instruction is a Prefix instruction then this instruction MUST go with it.
            //we cannot put an instruction between the two.
            if (instruction.Previous != null && instruction.Previous.OpCode.OpCodeType == OpCodeType.Prefix)
                return;

            if (config.HasOffset(method.FullName, instruction.Offset))
                return;

            if (lastLine != null && config.HasLine(method.FullName, lastLine)) {
                return;
            }

            var lineNum = -1;
            if (instruction.SequencePoint != null)
                lineNum = instruction.SequencePoint.StartLine;

            var line = string.Join(", ",
                                   "Method: " + method.FullName,
                                   "Line: " + lineNum,
                                   "Offset: " + instruction.Offset,
                                   "Instruction: " + instruction);

            writer.WriteLine(line);

            var pathParamLoadInstruction = worker.Create(OpCodes.Ldstr, config.HitsPath);
            var lineParamLoadInstruction = worker.Create(OpCodes.Ldc_I4, instrumentIndex);
            var registerInstruction = worker.Create(OpCodes.Call, countReference);

            //inserting method before instruction  because after will not happen after a method Ret instruction
            worker.InsertBefore(instruction, pathParamLoadInstruction);
            worker.InsertAfter(pathParamLoadInstruction, lineParamLoadInstruction);
            worker.InsertAfter(lineParamLoadInstruction, registerInstruction);

            ++instrumentIndex;

            //change try/finally etc to point to our first instruction if they referenced the one we inserted before
            foreach (var handler in method.Body.ExceptionHandlers) {
                if (handler.FilterStart == instruction)
                    handler.FilterStart = pathParamLoadInstruction;

                if (handler.TryStart == instruction)
                    handler.TryStart = pathParamLoadInstruction;
                if (handler.TryEnd == instruction)
                    handler.TryEnd = pathParamLoadInstruction;

                if (handler.HandlerStart == instruction)
                    handler.HandlerStart = pathParamLoadInstruction;
                if (handler.HandlerEnd == instruction)
                    handler.HandlerEnd = pathParamLoadInstruction;
            }

            //change instructions with a target instruction if they referenced the one we inserted before to be our first instruction
            foreach (var iteratedInstruction in method.Body.Instructions) {
                var operand = iteratedInstruction.Operand;
                if (operand == instruction) {
                    iteratedInstruction.Operand = pathParamLoadInstruction;
                    continue;
                }

                if (!(operand is Instruction[]))
                    continue;

                var operands = (Instruction[])operand;
                for (var i = 0; i < operands.Length; ++i) {
                    if (operands[i] == instruction)
                        operands[i] = pathParamLoadInstruction;
                }
            }
        }
Exemplo n.º 20
0
        private static void Instrument(string assemblyPath, InstrumentConfig config, TextWriter writer, ref int instrumentIndex)
        {
            //Mono.Cecil.[Mdb|Pdb].dll must be alongsize this exe to include sequence points from ReadSymbols
            var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { ReadSymbols = true });
            var countReference = assembly.MainModule.Import(countMethodInfo);

            foreach (var type in assembly.MainModule.GetTypes())//.Types doesnt include nested types
                Instrument(type, countReference, config, writer, ref instrumentIndex);

            assembly.Write(assemblyPath, new WriterParameters { WriteSymbols = true });

            var counterPath = typeof(Counter).Assembly.Location;

            File.Copy(counterPath, Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileName(counterPath)), true);
        }
Exemplo n.º 21
0
        private static void Instrument(TypeDefinition type, MethodReference countReference, InstrumentConfig config, TextWriter writer, ref int instrumentIndex)
        {
            if (type.FullName == "<Module>")
                return;

            if (!Regex.IsMatch(type.FullName, config.TypeInclude) || Regex.IsMatch(type.FullName, config.TypeExclude))
                return;

            foreach (var method in type.Methods.Where(m => m.HasBody))
                Instrument(method, countReference, config, writer, ref instrumentIndex);
        }
Exemplo n.º 22
0
        private static void Instrument(MethodDefinition method, MethodReference countReference, InstrumentConfig config, TextWriter writer, ref int instrumentIndex)
        {
            if (!Regex.IsMatch(method.FullName, config.MethodInclude) || Regex.IsMatch(method.FullName, config.MethodExclude))
                return;

            var worker = method.Body.GetILProcessor();

            method.Body.SimplifyMacros();

            string lastLine = null;//the sequence point for instructions that dont have one is the last set (if one exists)
            //need to copy instruction list since we modify using worker inserts
            foreach (var instruction in new List<Instruction>(method.Body.Instructions).OrderBy(i => i.Offset)) {
                var sequencePoint = instruction.SequencePoint;
                if (sequencePoint != null) {
                    var line = File.ReadLines(sequencePoint.Document.Url).ElementAtOrDefault(sequencePoint.StartLine - 1);
                    if (line != null)
                        lastLine = line;
                }

                Instrument(instruction, countReference, method, worker, lastLine, config, writer, ref instrumentIndex);
            }

            method.Body.OptimizeMacros();
        }
Exemplo n.º 23
0
        private static void Instrument (
                                      AssemblyDefinition assembly,
                                      TypeDefinition type,
                                       Instruction instruction,
                                       MethodReference countReference,
                                       MethodDefinition method,
                                       ILProcessor worker,
                                       string lastLine,
                                       InstrumentConfig config,
                                       TextWriter writer,
                                       ref int instrumentIndex)
        {
            //if the previous instruction is a Prefix instruction then this instruction MUST go with it.
            //we cannot put an instruction between the two.
            if (instruction.Previous != null && instruction.Previous.OpCode.OpCodeType == OpCodeType.Prefix)
                return;

            if (config.HasOffset (method.FullName, instruction.Offset))
                return;

            if (lastLine != null && config.HasLine (method.FullName, lastLine)) {
                return;
            }

            var lineNumStart = -1;
            var lineNumEnd = -1;
            if (instruction.SequencePoint != null) {
                lineNumStart = instruction.SequencePoint.StartLine;
                lineNumEnd = instruction.SequencePoint.EndLine;
            }

            var parentTypeRef = type;
            while (parentTypeRef.DeclaringType != null)
                parentTypeRef = parentTypeRef.DeclaringType;

            var line = string.Join ("\t",
                                   assembly.Name,  //0
                                   parentTypeRef.FullName,//1
                                   method.FullName, //2 
                                   lineNumStart, //3
                                   lineNumEnd, //4 
                                   instruction.Offset, //5
                                   instruction.ToString ().Replace ("\n", " "), //6
                                   instruction.SequencePoint?.Document.Url); //7

   
            writer.WriteLine (line);

            var pathParamLoadInstruction = worker.Create (OpCodes.Ldstr, config.HitsPathPrefix);
            var lineParamLoadInstruction = worker.Create (OpCodes.Ldc_I4, instrumentIndex);
            var registerInstruction = worker.Create (OpCodes.Call, countReference);

            //inserting method before instruction  because after will not happen after a method Ret instruction
            worker.InsertBefore (instruction, pathParamLoadInstruction);
            worker.InsertAfter (pathParamLoadInstruction, lineParamLoadInstruction);
            worker.InsertAfter (lineParamLoadInstruction, registerInstruction);

            ++instrumentIndex;

            //change try/finally etc to point to our first instruction if they referenced the one we inserted before
            foreach (var handler in method.Body.ExceptionHandlers) {
                if (handler.FilterStart == instruction)
                    handler.FilterStart = pathParamLoadInstruction;

                if (handler.TryStart == instruction)
                    handler.TryStart = pathParamLoadInstruction;
                if (handler.TryEnd == instruction)
                    handler.TryEnd = pathParamLoadInstruction;

                if (handler.HandlerStart == instruction)
                    handler.HandlerStart = pathParamLoadInstruction;
                if (handler.HandlerEnd == instruction)
                    handler.HandlerEnd = pathParamLoadInstruction;
            }

            //change instructions with a target instruction if they referenced the one we inserted before to be our first instruction
            foreach (var iteratedInstruction in method.Body.Instructions) {
                var operand = iteratedInstruction.Operand;
                if (operand == instruction) {
                    iteratedInstruction.Operand = pathParamLoadInstruction;
                    continue;
                }

                if (!(operand is Instruction []))
                    continue;

                var operands = (Instruction [])operand;
                for (var i = 0; i < operands.Length; ++i) {
                    if (operands [i] == instruction)
                        operands [i] = pathParamLoadInstruction;
                }
            }
        }
Exemplo n.º 24
0
        private static void Instrument(
		    TypeDefinition type,
		    MethodReference countReference,
		    InstrumentConfig config,
		    TextWriter writer,
		    ref int instrumentIndex)
        {
            if (type.FullName == "<Module>") {
                return;
            }

            if (!Regex.IsMatch(type.FullName, config.TypeInclude) || Regex.IsMatch(type.FullName, config.TypeExclude)
                || (type.CustomAttributes.Count() > 0 && type.CustomAttributes[0].Constructor.DeclaringType.ToString().Contains("ExcludeFromCodeCoverage"))) {
                return;
            }

            foreach (var method in type.Methods.Where(m => m.HasBody)) {
                Instrument(method, countReference, config, writer, ref instrumentIndex);
            }
        }
Exemplo n.º 25
0
        private static void Instrument(Instruction instruction,
                                       MethodReference countReference,
                                       MethodDefinition method,
                                       ILProcessor worker,
                                       string lastLine,
                                       InstrumentConfig config,
                                       TextWriter writer,
                                       ref int instrumentIndex)
        {
            //if the previous instruction is a Prefix instruction then this instruction MUST go with it.
            //we cannot put an instruction between the two.
            if (instruction.Previous != null && instruction.Previous.OpCode.OpCodeType == OpCodeType.Prefix)
            {
                return;
            }

            if (config.HasOffset(method.FullName, instruction.Offset))
            {
                return;
            }

            if (lastLine != null && config.HasLine(method.FullName, lastLine))
            {
                return;
            }

            var lineNum       = -1;
            var sequencePoint = method.DebugInformation.GetSequencePoint(instruction);

            if (sequencePoint != null)
            {
                lineNum = sequencePoint.StartLine;
            }

            var line = string.Join(", ",
                                   "Method: " + method.FullName,
                                   "Line: " + lineNum,
                                   "Offset: " + instruction.Offset,
                                   "Instruction: " + instruction);

            writer.WriteLine(line);

            var pathParamLoadInstruction = worker.Create(OpCodes.Ldstr, config.HitsPathPrefix);
            var lineParamLoadInstruction = worker.Create(OpCodes.Ldc_I4, instrumentIndex);
            var registerInstruction      = worker.Create(OpCodes.Call, countReference);

            //inserting method before instruction  because after will not happen after a method Ret instruction
            worker.InsertBefore(instruction, pathParamLoadInstruction);
            worker.InsertAfter(pathParamLoadInstruction, lineParamLoadInstruction);
            worker.InsertAfter(lineParamLoadInstruction, registerInstruction);

            ++instrumentIndex;

            //change try/finally etc to point to our first instruction if they referenced the one we inserted before
            foreach (var handler in method.Body.ExceptionHandlers)
            {
                if (handler.FilterStart == instruction)
                {
                    handler.FilterStart = pathParamLoadInstruction;
                }

                if (handler.TryStart == instruction)
                {
                    handler.TryStart = pathParamLoadInstruction;
                }
                if (handler.TryEnd == instruction)
                {
                    handler.TryEnd = pathParamLoadInstruction;
                }

                if (handler.HandlerStart == instruction)
                {
                    handler.HandlerStart = pathParamLoadInstruction;
                }
                if (handler.HandlerEnd == instruction)
                {
                    handler.HandlerEnd = pathParamLoadInstruction;
                }
            }

            //change instructions with a target instruction if they referenced the one we inserted before to be our first instruction
            foreach (var iteratedInstruction in method.Body.Instructions)
            {
                var operand = iteratedInstruction.Operand;
                if (operand == instruction)
                {
                    iteratedInstruction.Operand = pathParamLoadInstruction;
                    continue;
                }

                if (!(operand is Instruction[]))
                {
                    continue;
                }

                var operands = (Instruction[])operand;
                for (var i = 0; i < operands.Length; ++i)
                {
                    if (operands[i] == instruction)
                    {
                        operands[i] = pathParamLoadInstruction;
                    }
                }
            }
        }