Java @使用Kanela的可记录方法仪器
我想在我们的应用程序中设置一个可记录的工具,其思想与 因为我的团队将要使用Kamon和Kanela在我们的代码库中传播上下文,所以如果由同一个代理来执行所有的插装,对我们来说会简单得多 所以我想我应该自己动手,在我们的mono repo中启动一个新项目,安装一个kamon loggable模块。我已经研究了kamon注释和kamon注释api代码,以获得如何做到这一点的灵感。我找到的唯一一个文档()不是很有用,我对ByteBudy几乎一无所知。。。但cameleon编码在一开始就应该足够了:) 我到达了一个看起来不错的点,编译,但是在运行时,没有日志,代码似乎没有被执行。代码中的断点永远不会到达,但这可能是正常的,我不确定该类是否在插装之后实际实例化,或者代码是否在其他类中内联复制 任何关于如何设置项目的建议(没有双关语)或遗漏的东西,都将不胜感激。我想这与我的build.sbt或conf文件有关,但我现在已经被卡住了 构建.sbtJava @使用Kanela的可记录方法仪器,java,scala,instrumentation,javaagents,kamon,Java,Scala,Instrumentation,Javaagents,Kamon,我想在我们的应用程序中设置一个可记录的工具,其思想与 因为我的团队将要使用Kamon和Kanela在我们的代码库中传播上下文,所以如果由同一个代理来执行所有的插装,对我们来说会简单得多 所以我想我应该自己动手,在我们的mono repo中启动一个新项目,安装一个kamon loggable模块。我已经研究了kamon注释和kamon注释api代码,以获得如何做到这一点的灵感。我找到的唯一一个文档()不是很有用,我对ByteBudy几乎一无所知。。。但cameleon编码在一开始就应该足够了:)
// scala_common project contains the @com.company.logging.Loggable annotation declaration
// java project (but compiled as scala ?)
// nothing in the assembly, because no Main to be executed
lazy val loggable = (project in file("common/scala-kamon-loggable"))
.enablePlugins(JavaAgent)
.assembly("", "scala-kamon-loggable.jar")
.dependsOn(scala_common)
.settings(
javaAgents := Seq("io.kamon" % "kanela-agent" % "1.0.7" % "runtime")
)
.settings(
libraryDependencies ++= Seq(
"io.kamon" %% "kamon-core" % "2.1.4",
"io.kamon" %% "kamon-annotation" % "2.1.4"
)
)
// the main I execute to test
lazy val logging_poc = (project in file("applications/logging-poc"))
.assembly("com.company.logging.Poc", "logging-poc.jar")
.dependsOn(scala_common, loggable)
.settings(
libraryDependencies ++= Seq(
"io.kamon" %% "kamon-core" % "2.1.4",
"io.kamon" %% "kamon-scala-future" % "2.1.4",
"io.kamon" %% "kamon-logback" % "2.1.4"
)
)
scala普通版
- com.company.logging.Loggable
- reference.conf
- com.company.logging.Instrumentation
- com.company.logging.advisor.LoggableAdvisor
- com.company.logging.Poc
对象Poc通过LazyLogging扩展应用程序{
val config=ConfigFactory.load()
if(config.getBoolean(“kamon.enabled”)){
Kamon.loadModules()
}
导入scala.concurrent.ExecutionContext.Implicits.global
@com.company.logging.Loggable
def asyncLog(参数:整数):未来[字符串]={
Kamon.runWithSpan(Kamon.spanBuilder(“级别3”).start(),finishSpan=true){
未来{
阻塞{
断言(参数<5,“参数太大”)
线程睡眠(参数*1000)
logger.info(s“一些信息日志!($param)”)
“好的”
}
}
}
}
wait.ready(异步日志(0),Duration.Inf)
ready(Kamon.stopModules(),Duration.Inf)
}
这是我在控制台中得到的跟踪(另一个仪器工作,正如我们在MDC中看到的SpanId)。
我希望在“一些信息日志”之前有一行“内部检测”
\uuuuuu______
| |/ / | | \ \ \ \
| ' / __ _ _ __ ___| | __ _ \ \ \ \
| < / _` | '_ \ / _ \ |/ _` | ) ) ) )
| . \ (_| | | | | __/ | (_| | / / / /
|_|\_\__,_|_| |_|\___|_|\__,_| /_/_/_/
==============================
与Kanela一起运行的Kamon Instrumentation Agent::
scala-execution-context-global-18 10:53:14.582[INFO]com.company.logging.Poc$-一些信息日志!(0)-MDC[kamonSpanId=0b64e07a7ec37656,kamonTraceId=c3474442849cccd86,kamonSpanName=level3]
进程已完成,退出代码为0
import java.lang.annotation.*;
/**
* When instrumentation is activated, log all entry / return / throw of the annotated method
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {}
kanela.modules {
loggable {
enabled = true
name = "Loggable Annotation Instrumentation"
description = "Provides an annotation to create tracing Logs of annotated methods"
instrumentations = [
"com.company.logging.Instrumentation"
]
}
}
public final class Instrumentation extends InstrumentationBuilder {
private static final String Loggable = "com.company.logging.Loggable";
public Instrumentation() {
onTypesWithMethodsAnnotatedWith(Loggable)
.advise(isAnnotatedWith(named(Loggable)), LoggableAdvisor.class);
}
}
public final class LoggableAdvisor {
public final static ExecutionContext CallingThreadEC = CallingThreadExecutionContext$.MODULE$;
@Advice.OnMethodEnter()
public static void onEnter(
@Advice.This(optional = true) Object obj,
@Advice.Origin Class<?> clazz,
@Advice.Origin Method method,
@Advice.Origin("#t") String className,
@Advice.Origin("#m") String methodName,
@Advice.Origin("#s") String signatureName,
@Advice.AllArguments Object[] allArguments
) {
// I'd put a Logger after, for now, just for testing instrumentation, println is enough
System.out.println("INSIDE INSTRUMENTATION");
}
}
kamon {
trace {
tick-interval = 2 seconds
sampler = "always"
}
enabled: true
}
object Poc extends App with LazyLogging {
val config = ConfigFactory.load()
if (config.getBoolean("kamon.enabled")) {
Kamon.loadModules()
}
import scala.concurrent.ExecutionContext.Implicits.global
@com.company.logging.Loggable
def asyncLog(param: Integer): Future[String] = {
Kamon.runWithSpan(Kamon.spanBuilder("Level 3").start(), finishSpan = true) {
Future {
blocking {
assert(param < 5, "Param is too big")
Thread.sleep(param * 1000)
logger.info(s"Some info logs ! ($param)")
"Ok"
}
}
}
}
Await.ready( asyncLog(0) , Duration.Inf)
Await.ready(Kamon.stopModules(), Duration.Inf)
}
_ __ _ ______
| |/ / | | \ \ \ \
| ' / __ _ _ __ ___| | __ _ \ \ \ \
| < / _` | '_ \ / _ \ |/ _` | ) ) ) )
| . \ (_| | | | | __/ | (_| | / / / /
|_|\_\__,_|_| |_|\___|_|\__,_| /_/_/_/
==============================
Running with Kanela, the Kamon Instrumentation Agent ::
scala-execution-context-global-18 10:53:14.582 [INFO ] com.company.logging.Poc$ - Some info logs ! (0) - MDC[kamonSpanId=0b64e07a7ec37656, kamonTraceId=c347442849cccd86, kamonSpanName=Level 3]
Process finished with exit code 0