Skip to content
Permalink
Browse files

Initial integration of micrometer instrumentation and prometheus impl…

…ementation. (#419)
  • Loading branch information
brettmorien committed Feb 14, 2020
1 parent 688c15f commit 27d6e0a0d69429a5bcb52469511dfbe034b42596
@@ -0,0 +1,19 @@
k8s_yaml(helm(
'./charts/orbit',
name='orbit',
namespace="orbit"
))

docker_build('orbitframework/orbit',
'.',
dockerfile='./docker/server/Dockerfile',
only=[
'src/orbit-application/build/libs',
'docker'
],
live_update=[sync('src/orbit-application/build/libs', '/opt/orbit/libs')]
)

k8s_resource('orbit',
port_forwards=['50056:50056', '5005:5005', '8080:8080']
)
@@ -13,20 +13,27 @@ data:
"url": "{{ .Values.url }}",
"port": "{{ .Values.node.containerPort }}"
}
{{- if gt (int .Values.nodeDirectory.replicas) 0 }}
{{- if gt (int .Values.nodeDirectory.replicas) 0 }}
,"nodeDirectory": [
"orbit.server.etcd.EtcdNodeDirectory$EtcdNodeDirectoryConfig",
{
"url": "http://{{ include "orbit.fullname" . }}-node-directory:{{ .Values.nodeDirectory.clientPort }}"
}
]
{{- end }}
{{- if gt (int .Values.addressableDirectory.replicas) 0 }}
{{- end }}
{{- if gt (int .Values.addressableDirectory.replicas) 0 }}
,"addressableDirectory": [
"orbit.server.etcd.EtcdAddressableDirectory$EtcdAddressableDirectoryConfig",
{
"url": "http://{{ include "orbit.fullname" . }}-addressable-directory:{{ .Values.addressableDirectory.clientPort }}"
}
]
{{- end }}
{{- end }}
,"meterRegistry": [
"orbit.server.prometheus.PrometheusMetrics$PrometheusMetricsConfig",
{
"url": "/metrics",
"port": 8080
}
]
}
@@ -13,6 +13,7 @@ include(":src:orbit-shared")
include(":src:orbit-server")
include(":src:orbit-server-etcd")
include(":src:orbit-application")
include(":src:orbit-prometheus")

include(":src:orbit-client")

@@ -16,6 +16,7 @@ plugins {
dependencies {
implementation(project(":src:orbit-server"))
implementation(project(":src:orbit-server-etcd"))
implementation(project(":src:orbit-prometheus"))
implementation(project(":src:orbit-shared"))
implementation(project(":src:orbit-util"))

@@ -12,7 +12,6 @@ plugins {
dependencies {
implementation(project(":src:orbit-server"))
implementation(project(":src:orbit-client"))

}

jmh {
@@ -0,0 +1,18 @@
/*
Copyright (C) 2015 - 2019 Electronic Arts Inc. All rights reserved.
This file is part of the Orbit Project <https://www.orbit.cloud>.
See license in LICENSE.
*/
val grpcVersion = project.rootProject.ext["grpcVersion"]

plugins {
kotlin("jvm")
`maven-publish`
}

dependencies {
implementation(project(":src:orbit-util"))
implementation(project(":src:orbit-shared"))

implementation("io.micrometer:micrometer-registry-prometheus:latest.release")
}
@@ -0,0 +1,33 @@
/*
Copyright (C) 2015 - 2020 Electronic Arts Inc. All rights reserved.
This file is part of the Orbit Project <https://www.orbit.cloud>.
See license in LICENSE.
*/

package src.main.kotlin.orbit.prometheus

import com.sun.net.httpserver.HttpServer
import io.micrometer.prometheus.PrometheusMeterRegistry
import java.io.PrintWriter
import java.net.InetSocketAddress

class PrometheusMeterEndpoint(
registry: PrometheusMeterRegistry,
endpoint: String = "/metrics",
port: Int = 8080
) {
init {
HttpServer.create(InetSocketAddress(port), 0).apply {

createContext(endpoint) { http ->
http.responseHeaders.add("Content-type", "text/plain")
http.sendResponseHeaders(200, 0)
PrintWriter(http.responseBody).use { out ->
out.println(registry.scrape())
}
}

start()
}
}
}
@@ -0,0 +1,27 @@
/*
Copyright (C) 2015 - 2020 Electronic Arts Inc. All rights reserved.
This file is part of the Orbit Project <https://www.orbit.cloud>.
See license in LICENSE.
*/

package orbit.server.prometheus

import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.prometheus.PrometheusConfig
import io.micrometer.prometheus.PrometheusMeterRegistry
import mu.KotlinLogging
import orbit.util.di.ExternallyConfigured
import src.main.kotlin.orbit.prometheus.PrometheusMeterEndpoint


class PrometheusMetrics(config: PrometheusMetricsConfig) : PrometheusMeterRegistry(PrometheusConfig.DEFAULT) {
data class PrometheusMetricsConfig(
val url: String = "/metrics",
val port: Int = 8080
) : ExternallyConfigured<MeterRegistry> {
override val instanceType: Class<out MeterRegistry> = PrometheusMetrics::class.java
}

private val logger = KotlinLogging.logger {}
private val meterServer = PrometheusMeterEndpoint(this, config.url, config.port)
}
@@ -18,4 +18,5 @@ dependencies {
implementation("io.grpc:grpc-netty-shaded:$grpcVersion")
implementation("org.jgrapht:jgrapht-core:1.3.1")

implementation("io.micrometer:micrometer-core:1.3.5")
}
@@ -6,6 +6,7 @@

package orbit.server

import io.micrometer.core.instrument.MeterRegistry
import kotlinx.coroutines.launch
import mu.KotlinLogging
import orbit.server.auth.AuthSystem
@@ -74,6 +75,7 @@ class OrbitServer(private val config: OrbitServerConfig) {
private val pipeline by container.inject<Pipeline>()
private val remoteMeshNodeManager by container.inject<RemoteMeshNodeManager>()


private val ticker = ConstantTicker(
scope = runtimeScopes.cpuScope,
targetTickRate = config.tickRate.toMillis(),
@@ -124,6 +126,7 @@ class OrbitServer(private val config: OrbitServerConfig) {
definition<RemoteMeshNodeManager>()
externallyConfigured(config.nodeDirectory)
externallyConfigured(config.addressableDirectory)
externallyConfigured(config.meterRegistry)

// Auth
definition<AuthSystem>()
@@ -6,12 +6,14 @@

package orbit.server

import io.micrometer.core.instrument.MeterRegistry
import kotlinx.coroutines.CoroutineDispatcher
import orbit.server.mesh.AddressableDirectory
import orbit.server.mesh.LeaseDuration
import orbit.server.mesh.LocalServerInfo
import orbit.server.mesh.NodeDirectory
import orbit.server.mesh.local.LocalAddressableDirectory
import orbit.server.mesh.local.LocalMeterRegistry
import orbit.server.mesh.local.LocalNodeDirectory
import orbit.util.concurrent.Pools
import orbit.util.di.ExternallyConfigured
@@ -79,8 +81,13 @@ data class OrbitServerConfig(
val nodeDirectory: ExternallyConfigured<NodeDirectory> = LocalNodeDirectory.LocalNodeDirectorySingleton,

/**
* The a oddressable directory to use
* The addressable directory to use
*/
val addressableDirectory: ExternallyConfigured<AddressableDirectory> = LocalAddressableDirectory.LocalAddressableDirectorySingleton
val addressableDirectory: ExternallyConfigured<AddressableDirectory> = LocalAddressableDirectory.LocalAddressableDirectorySingleton,

)
/**
* The meter registry implementation for sending application metrics
*/
val meterRegistry: ExternallyConfigured<MeterRegistry> = LocalMeterRegistry.LocalMeterRegistrySingleton
) {
}
@@ -0,0 +1,24 @@
/*
Copyright (C) 2015 - 2020 Electronic Arts Inc. All rights reserved.
This file is part of the Orbit Project <https://www.orbit.cloud>.
See license in LICENSE.
*/

package orbit.server.mesh.local

import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.simple.SimpleMeterRegistry
import mu.KotlinLogging
import orbit.util.di.ExternallyConfigured

val logger = KotlinLogging.logger {}

class LocalMeterRegistry : SimpleMeterRegistry() {
object LocalMeterRegistrySingleton : ExternallyConfigured<MeterRegistry> {
override val instanceType = LocalMeterRegistry::class.java
}

init {
logger.info("Starting simple meter reg")
}
}
@@ -8,10 +8,12 @@ package orbit.server.service

import grpc.health.v1.HealthImplBase
import grpc.health.v1.HealthOuterClass
import kotlinx.coroutines.channels.ReceiveChannel
import io.micrometer.core.instrument.MeterRegistry

class HealthService(private val checks: HealthCheckList) : HealthImplBase() {
class HealthService(private val checks: HealthCheckList, private val metrics: MeterRegistry) : HealthImplBase() {
private val counter = metrics.counter("orbit", "health", "check")
override suspend fun check(request: HealthOuterClass.HealthCheckRequest): HealthOuterClass.HealthCheckResponse {
counter.increment()
return HealthOuterClass.HealthCheckResponse.newBuilder()
.setStatus(
if (this.isHealthy()) {
@@ -22,10 +24,6 @@ class HealthService(private val checks: HealthCheckList) : HealthImplBase() {
).build()
}

override fun watch(request: HealthOuterClass.HealthCheckRequest): ReceiveChannel<HealthOuterClass.HealthCheckResponse> {
return super.watch(request)
}

suspend fun isHealthy(): Boolean {
return checks.getChecks().all { check -> check.isHealthy() }
}

0 comments on commit 27d6e0a

Please sign in to comment.
You can’t perform that action at this time.