diff options
-rw-r--r-- | kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala | 85 | ||||
-rw-r--r-- | kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala | 6 |
2 files changed, 77 insertions, 14 deletions
diff --git a/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala b/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala index 0ad7fdf7..eb0c46df 100644 --- a/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala +++ b/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala @@ -15,18 +15,20 @@ package kamon.autoweave.loader -import java.io.{ File, FileOutputStream, InputStream } +import java.io.{File, FileOutputStream, InputStream} import java.lang.management.ManagementFactory +import java.lang.reflect.Constructor import java.util import java.util.jar.Attributes.Name -import java.util.jar.{ JarEntry, JarOutputStream, Manifest } +import java.util.jar.{JarEntry, JarOutputStream, Manifest} import com.sun.tools.attach.spi.AttachProvider -import com.sun.tools.attach.{ VirtualMachine, VirtualMachineDescriptor } +import com.sun.tools.attach.{VirtualMachine, VirtualMachineDescriptor} +import kamon.autoweave.loader.resolver.OsResolver._ import sun.tools.attach._ import scala.util.control.NoStackTrace -import scala.util.{ Failure, Success, Try } +import scala.util.{Failure, Success, Try} object AgentLoader { @@ -118,12 +120,13 @@ object AgentLoader { * @return * Returns the HotSpotVirtualMachine implementation of the running JVM. */ - private def findVirtualMachineImplementation(): Try[Class[_ <: HotSpotVirtualMachine]] = System.getProperty("os.name") match { - case os if os.startsWith("Windows") ⇒ Success(classOf[WindowsVirtualMachine]) - case os if os.startsWith("Mac OS X") ⇒ Success(classOf[BsdVirtualMachine]) - case os if os.startsWith("Solaris") ⇒ Success(classOf[SolarisVirtualMachine]) - case os if os.startsWith("Linux") || os.startsWith("LINUX") ⇒ Success(classOf[LinuxVirtualMachine]) - case other ⇒ Failure(new RuntimeException(s"Cannot use Attach API on unknown OS: $other") with NoStackTrace) + private def findVirtualMachineImplementation(): Try[Class[_ <: HotSpotVirtualMachine]] = currentOs match { + case Windows(_, _, _) ⇒ Success(classOf[WindowsVirtualMachine]) + case Mac(_, _, _) ⇒ Success(classOf[BsdVirtualMachine]) + case Solaris(_, _, _) ⇒ Success(classOf[SolarisVirtualMachine]) + case Linux(_, _, _) ⇒ Success(classOf[LinuxVirtualMachine]) + case UnknownOs(name, arch, version) ⇒ + Failure(new RuntimeException(s"Cannot use Attach API on unknown OS: $name Arch: $arch Version: $version") with NoStackTrace) } /** @@ -144,11 +147,69 @@ object AgentLoader { case Success(vmClass) ⇒ val pid = getPidFromRuntimeMBean // This is only done with Reflection to avoid the JVM pre-loading all the XyzVirtualMachine classes. - val vmConstructor = vmClass.getConstructor(classOf[AttachProvider], classOf[String]) - val newVM = vmConstructor.newInstance(AttachProvider, pid) + val newVM = vmConstructor(vmClass).newInstance(AttachProvider, pid) newVM.asInstanceOf[VirtualMachine] case Failure(reason) ⇒ throw reason } } + + /** + * `BsdVirtualMachine`, used when your platform is Mac - vmClass parameter, has the constructor + * without modifier (by default is `package-private`), so `AgentLoader` can not instance it, for that reason + * we need to set accessible that constructor via reflection. + * + * @param vmClass + * @return + */ + private def vmConstructor(vmClass: Class[_ <: HotSpotVirtualMachine]): Constructor[_] = { + currentOs match { + case Mac(_, _, _) ⇒ + val vmC = vmClass.getDeclaredConstructor(classOf[AttachProvider], classOf[String]) + vmC.setAccessible(true) + vmC + + case _ ⇒ vmClass.getConstructor(classOf[AttachProvider], classOf[String]) + } + } } +package object resolver { + + /* OS RESOLVERS */ + private[loader] object OsResolver { + private[resolver] trait OsIdentifiable { + def name: String + def arch: String + def version: String + } + + private[loader] case class Windows(name: String, arch: String, version: String) extends OsIdentifiable + private[loader] case class Mac(name: String, arch: String, version: String) extends OsIdentifiable + private[loader] case class Solaris(name: String, arch: String, version: String) extends OsIdentifiable + private[loader] case class Linux(name: String, arch: String, version: String) extends OsIdentifiable + private[loader] case class UnknownOs(name: String, arch: String, version: String) extends OsIdentifiable + + private[resolver] val osName = System.getProperty("os.name") + private[resolver] val osArch = System.getProperty("os.arch") + private[resolver] val osVersion = System.getProperty("os.version") + + private[this] val defaultWindowsName = "Windows" + private[this] val defaultMacName = "Mac OS X" + private[this] val defaultSolarisName = "Solaris" + private[this] val defaultLinuxName = "Linux" + private[this] val defaultLinuxUpperCaseName = defaultLinuxName.toUpperCase + + /** + * Resolver OS based on java properties. + */ + val currentOs: OsIdentifiable = osName match { + case os if os.startsWith(defaultWindowsName) ⇒ Windows(os, osArch, osVersion) + case os if os.startsWith(defaultMacName) ⇒ Mac(os, osArch, osVersion) + case os if os.startsWith(defaultSolarisName) ⇒ Solaris(os, osArch, osVersion) + case os if os.startsWith(defaultLinuxName) || os.startsWith(defaultLinuxUpperCaseName) ⇒ Linux(os, osArch, osVersion) + case other ⇒ UnknownOs(other, osArch, osVersion) + } + } + /* OS RESOLVERS */ + +} diff --git a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala index 869bcc12..c044719c 100644 --- a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala +++ b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala @@ -52,7 +52,8 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, iz val traceElapsedTime = NanoInterval.since(startTimestamp) _elapsedTime = traceElapsedTime - Kamon.metrics.entity(TraceMetrics, name).elapsedTime.record(traceElapsedTime.nanos) + if (Kamon.metrics.shouldTrack(name, TraceMetrics.category)) + Kamon.metrics.entity(TraceMetrics, name).elapsedTime.record(traceElapsedTime.nanos) drainFinishedSegments() } @@ -67,7 +68,8 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, iz "category" -> segment.category, "library" -> segment.library) - Kamon.metrics.entity(SegmentMetrics, segment.name, segmentTags).elapsedTime.record(segment.duration.nanos) + if (Kamon.metrics.shouldTrack(segment.name, SegmentMetrics.category)) + Kamon.metrics.entity(SegmentMetrics, segment.name, segmentTags).elapsedTime.record(segment.duration.nanos) drainFinishedSegments() } } |