Skip to content

Commit

Permalink
WIP MORE WIP WIP WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
SimunKaracic committed Oct 21, 2020
1 parent c9227d7 commit 93b118a
Show file tree
Hide file tree
Showing 11 changed files with 382 additions and 381 deletions.
Original file line number Diff line number Diff line change
@@ -1,82 +1,62 @@
package kamon.armeria.instrumentation;

import com.linecorp.armeria.common.HttpRequest;
import com.linecorp.armeria.server.RequestConverter;
import com.linecorp.armeria.server.ServiceRequestContext;
import io.netty.util.AttributeKey;
import kamon.Kamon;
import kamon.context.Storage;
import kamon.instrumentation.http.HttpMessage;
import kamon.instrumentation.http.HttpServerInstrumentation;
import kamon.trace.Span;
import kamon.trace.SpanPropagation.B3;
import kanela.agent.libs.net.bytebuddy.asm.Advice;
import scala.Int;
import scala.Option;

// why is this good?
// i mean, the serve method could still spawn some shit off
// and go to another thread?
// ok, so this is about context propagation, right?
// when I store the context, how do other threads know about that?
// how does it FORWARD THAT INFORMATION to other threads?
// the information that yeah, there's a current trace in progress
// and you're a part of it
import java.util.Map;

public class ArmeriaHttpServiceInstrumentation {
@Advice.OnMethodEnter()
private static void enter(
@Advice.Local("scope") Storage.Scope scope,
@Advice.Local("span") Span span,
@Advice.This Object service,
private static Storage.Scope enter(
@Advice.Argument(0) ServiceRequestContext context,
@Advice.Argument(1) HttpRequest request) {
// what can I do with the context?
// What can i extract out of it?

// make sure that this _is_ truly available here
long startTime = context.log().partial().requestStartTimeNanos();

// I add a header here with the traceID right?
// I mean not here, but at the beginning of the pipeline
// is toString needed here?
// the the elastic-armeria shit without is too
// context.log().context().setAttr(AttributeKey.newInstance("Kamon.Context"), Kamon.currentContext());
// System.out.println("Context:");
// System.out.println("Context:");
// System.out.println(context);
// System.out.println("Request");
// System.out.println("Request");
// System.out.println(request);
// System.out.println("Service??");
// System.out.println("Service??");
// System.out.println(service);
// System.out.println(service.getClass().getEnclosingClass().getSimpleName());
// System.out.println("Context again");
// System.out.println("Context again");
// System.out.println(context.log().context());
// figure out how to get the host and the port
// also, this handler will need to end this span at the end of the pipeline
// meaning, we need to propagate it there somehow
HttpServerInstrumentation httpServerInstrumentation = HttpServerInstrumentation.from(Kamon.config().getConfig("kamon.instrumentation.armeria.http-server"),
"armeria.http.server", "0.0.0.0", 1234);
HttpServerInstrumentation.RequestHandler handler = httpServerInstrumentation
.createHandler(RequestConverter.toRequest(request, "whatever", 1234), true);
// context.log().whenComplete().thenAccept(requestLog -> {
// // shit
// handler.responseSent();
// // this takes a time
// // Kamon.Clock to convert it
// // but which time to use?
//// handler.span().finish();
// });
// add a decorator
// which has acces to this same context
// context.attr, modify response
// context.respo
context.setAttr(AttributeKey.newInstance("myHandler"), handler);

// this is wrong
// i should be starting a span here
// what tags do I add to it?
span = Kamon.serverSpanBuilder("some.smart.operation.name", "armeria???").start();
// parentSpan?
// wrong context to store?
scope = Kamon.storeContext(Kamon.currentContext());
// figure out a nice name
handler.span().name("CoolName").takeSamplingDecision();
return Kamon.storeContext(handler.context());
}

@Advice.OnMethodExit()
private static void exit(@Advice.Local("scope") Storage.Scope scope,
@Advice.Local("span") Span span,
@Advice.This Object service,
@Advice.Argument(0) ServiceRequestContext context,
@Advice.Argument(1) HttpRequest request) {
// how do i tell here if the thing finished correctly
// or if I should fail the span?
System.out.println("Context:");
System.out.println("Context:");
System.out.println(context);
System.out.println("Request");
System.out.println("Request");
System.out.println(request);
System.out.println("Service??");
System.out.println("Service??");
System.out.println(service);
System.out.println(service.getClass().getEnclosingClass().getSimpleName());
span.finish();
// Advice.Enter will bind the return from the enter to the exit :O
// :O :O :O :O :O
private static void exit(@Advice.Enter Storage.Scope scope) {
scope.close();
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.linecorp.armeria.server

import com.linecorp.armeria.common.HttpRequest
import kamon.instrumentation.http.HttpMessage

import scala.collection.JavaConverters.iterableAsScalaIterableConverter

object RequestConverter {
def toRequest(request: HttpRequest, serverHost: String, serverPort: Int): HttpMessage.Request = new HttpMessage.Request {

override def url: String = request.uri().toString

override def path: String = request.path()

override def method: String = request.method().name()

override def host: String = serverHost

override def port: Int = serverPort

override def read(header: String): Option[String] =
Option(request.headers().get(header))

override def readAll(): Map[String, String] =
request.headers().asScala.map(e => e.getKey.toString() -> e.getValue).toMap
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ kamon.instrumentation.armeria {
# - default: Uses the set default operation name
# - method: Uses the request HTTP method as the operation name.
#
name-generator = "kamon.armeria.instrumentation.server.KamonArmeriaOperationNameGenerator"
# name-generator = "kamon.armeria.instrumentation.server.KamonArmeriaOperationNameGenerator"

# Provides custom mappings from HTTP paths into operation names. Meant to be used in cases where the bytecode
# instrumentation is not able to provide a sensible operation name that is free of high cardinality values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ class ArmeriaHttpServerInstrumentation extends InstrumentationBuilder {
// onSubTypesOf("io.netty.channel.Channel")
// .mixin(classOf[HasRequestProcessingContextMixin])
//
// onType("com.linecorp.armeria.server.HttpServerPipelineConfigurator")
// .bridge(classOf[HttpPipelineConfiguratorInternalState])
// .advise(method("configureHttp"), classOf[ConfigureMethodAdvisor])
onType("com.linecorp.armeria.server.HttpServerPipelineConfigurator")
.bridge(classOf[HttpPipelineConfiguratorInternalState])
.advise(method("configureHttp"), classOf[ConfigureMethodAdvisor])
//
// onType("com.linecorp.armeria.server.FallbackService")
// .advise(method("serve"), classOf[ServeMethodAdvisor])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class ArmeriaHttpServerResponseHandler(serverInstrumentation: HttpServerIn
else {
val response = msg.asInstanceOf[HttpResponse]
val processingContext = ctx.channel().asInstanceOf[HasRequestProcessingContext].getRequestProcessingContext
response.

/**
* processingContext.requestHandler.span.operationName() will be empty if an HttpStatusException is thrown
Expand Down
20 changes: 3 additions & 17 deletions instrumentation/kamon-armeria/src/test/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ kamon.instrumentation.armeria {
# - default: Uses the set default operation name
# - method: Uses the request HTTP method as the operation name.
#
name-generator = "kamon.armeria.instrumentation.server.KamonArmeriaOperationNameGenerator"
# name-generator = "kamon.armeria.instrumentation.server.KamonArmeriaOperationNameGenerator"

# Provides custom mappings from HTTP paths into operation names. Meant to be used in cases where the bytecode
# instrumentation is not able to provide a sensible operation name that is free of high cardinality values.
Expand All @@ -153,7 +153,7 @@ kamon.instrumentation.armeria {
# The patterns are expressed as globs and the operation names are free form.
#
mappings {
"/dummy-resources/*/other-resources/*" = "dummy-resources/{}/other-resources/{}"
# "/dummy-resources/*/other-resources/*" = "dummy-resources/{}/other-resources/{}"
}
}
}
Expand Down Expand Up @@ -232,24 +232,10 @@ kamon.instrumentation.armeria {
# - hostname: Uses the request Host as the operation name.
# - method: Uses the request HTTP method as the operation name.
#
name-generator = "kamon.armeria.instrumentation.client.KamonArmeriaOperationNameGenerator"
# name-generator = "kamon.armeria.instrumentation.client.KamonArmeriaOperationNameGenerator"
}
}
}

}

kanela {
show-banner = false
modules {
armeria {
name = "Armeria instrumentation"
stoppable = true
instrumentations = [
"kamon.armeria.instrumentation.server.ArmeriaHttpServerInstrumentation",
"kamon.armeria.instrumentation.client.ArmeriaHttpClientInstrumentation"
]
within = [ "io.netty..*", "com.linecorp.armeria..*"]
}
}
}
Loading

0 comments on commit 93b118a

Please sign in to comment.