diff options
Diffstat (limited to 'kamon-core/src/main/scala/kamon/status')
3 files changed, 125 insertions, 6 deletions
diff --git a/kamon-core/src/main/scala/kamon/status/JsonMarshalling.scala b/kamon-core/src/main/scala/kamon/status/JsonMarshalling.scala index 5a3f22dc..370ab467 100644 --- a/kamon-core/src/main/scala/kamon/status/JsonMarshalling.scala +++ b/kamon-core/src/main/scala/kamon/status/JsonMarshalling.scala @@ -6,6 +6,8 @@ import java.lang.{StringBuilder => JavaStringBuilder} import com.typesafe.config.ConfigRenderOptions import kamon.module.Module +import scala.collection.JavaConverters.{iterableAsScalaIterableConverter, mapAsScalaMapConverter} + trait JsonMarshalling[T] { @@ -96,4 +98,33 @@ object JsonMarshalling { .done() } } + + implicit object InstrumentationStatusJsonMarshalling extends JsonMarshalling[Status.Instrumentation] { + override def toJson(instance: Status.Instrumentation, builder: JavaStringBuilder): Unit = { + val instrumentationObject = JsonWriter.on(builder) + .`object`() + .value("isActive", instance.isIActive) + .`object`("modules") + + instance.modules.asScala.foreach { + case (moduleName, moduleDescription) => instrumentationObject.value(moduleName, moduleDescription) + } + + instrumentationObject + .end() // end modules + .`object`("errors") + + instance.errors.asScala.foreach { + case (moduleName, errors) => + instrumentationObject.array(moduleName) + errors.asScala.foreach(t => instrumentationObject.value(t.toString)) + instrumentationObject.end() + } + + instrumentationObject + .end() // errors + .end() // object + .done() + } + } }
\ No newline at end of file diff --git a/kamon-core/src/main/scala/kamon/status/Status.scala b/kamon-core/src/main/scala/kamon/status/Status.scala index dc059277..2a52b95f 100644 --- a/kamon-core/src/main/scala/kamon/status/Status.scala +++ b/kamon-core/src/main/scala/kamon/status/Status.scala @@ -6,23 +6,50 @@ import kamon.metric.MetricRegistry import kamon.{Configuration, Environment, Kamon} import kamon.module.ModuleRegistry import kamon.module.Module.{Kind => ModuleKind} +import java.util.{Collections, Map => JavaMap, List => JavaList} /** - * Allows accessing of component's status APIs without exposing any other internal API from those components. + * Exposes Kamon components' status information. This is meant to be used for informational and debugging purposes. */ class Status(_moduleRegistry: ModuleRegistry, _metricRegistry: MetricRegistry, configuration: Configuration) { + /** + * Settings currently used by Kamon. + */ def settings(): Status.Settings = Status.Settings(BuildInfo.version, Kamon.environment, configuration.config()) /** - * Information about what modules have been detected in the classpath and their current status. + * Status of the module registry. Describes what modules have been detected in the classpath and their current + * statuses. */ def moduleRegistry(): Status.ModuleRegistry = _moduleRegistry.status() + /** + * Status of the metric registry. Describes all metrics currently tracked by Kamon. + */ def metricRegistry(): Status.MetricRegistry = _metricRegistry.status() + + + /** + * PRIVATE API. + * + * Status of instrumentation modules that have been detected and/or loaded into the current JVM. This + * API is not meant to be used by the general public. + * + * Read the [[Status.Instrumentation]] companion object's docs for more information. + */ + private[kamon] def instrumentation(): Status.Instrumentation = { + import Status.Instrumentation._ + + Status.Instrumentation( + isActive(), + modules(), + errors() + ) + } } @@ -57,4 +84,63 @@ object Status { tags: Map[String, String], instrumentType: InstrumentType ) + + + /** + * Status of the instrumentation modules. This data is completely untyped and not expected to be used anywhere + * outside Kamon. + */ + private[kamon] case class Instrumentation( + isIActive: Boolean, + modules: JavaMap[String, String], + errors: JavaMap[String, JavaList[Throwable]] + ) + + + /** + * This object works as a bridge between Kamon and Kanela to gather information about instrumentation modules. When + * instrumentation is enabled, it should replace the implementation of the members of this object and return proper + * information. + * + * This data is only exposed directly to the status page API because it lacks any sort of type safety. We might + * change this in the future and provide proper types for all instrumentation modules' info. + */ + private[kamon] object Instrumentation { + + /** + * Whether instrumentation is active or not. When Kanela is present it will replace this method to return true. + */ + def isActive(): Boolean = + false + + /** + * List all instrumentation modules known and their current status. The result map contains the module name as keys + * and a JSON representation of the module status as values. The expected structure in the JSON representations is + * as follows: + * + * { + * 'description': 'A explicative module description', + * 'isEnabled': true | false, + * 'isActive': true | false + * } + * + * The "isEnabled" flag tells whether the module is able to instrument classes or not. By default, all modules are + * able to instrument classes but some modules might be shipped in a disabled state or forced to be disabled via + * configuration. + * + * The "isActive" flag tells whether the modules has already applied instrumentation to any of its target classes. + * + */ + def modules(): JavaMap[String, String] = + Collections.emptyMap() + + + /** + * List all errors that might have happened during the instrumentation initialization. The resulting map contains + * a list of modules and any exceptions thrown by them during initialization. If not exceptions are thrown the map + * will always be empty. + */ + def errors(): JavaMap[String, JavaList[Throwable]] = + Collections.emptyMap() + } } diff --git a/kamon-core/src/main/scala/kamon/status/StatusPageServer.scala b/kamon-core/src/main/scala/kamon/status/StatusPageServer.scala index 35273f39..2784b87a 100644 --- a/kamon-core/src/main/scala/kamon/status/StatusPageServer.scala +++ b/kamon-core/src/main/scala/kamon/status/StatusPageServer.scala @@ -17,10 +17,11 @@ class StatusPageServer(hostname: String, port: Int, resourceLoader: ClassLoader, // Serve the current status data on Json. session.getUri() match { - case "/status/settings" => json(status.settings()) - case "/status/modules" => json(status.moduleRegistry()) - case "/status/metrics" => json(status.metricRegistry()) - case _ => NotFound + case "/status/settings" => json(status.settings()) + case "/status/modules" => json(status.moduleRegistry()) + case "/status/metrics" => json(status.metricRegistry()) + case "/status/instrumentation" => json(status.instrumentation()) + case _ => NotFound } } else { @@ -43,6 +44,7 @@ class StatusPageServer(hostname: String, port: Int, resourceLoader: ClassLoader, case "css" => "text/css" case "js" => "application/javascript" case "ico" => "image/x-icon" + case "svg" => "image/svg+xml" case "html" => "text/html" case _ => "text/plain" } |