Skip to content

Commit

Permalink
Migrated to own fork of management package.
Browse files Browse the repository at this point in the history
Now proudly scala 2.9.1
Statistics / metrics in JSON
  • Loading branch information
mwall committed Dec 28, 2011
1 parent 8bad1c2 commit 17f309f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 33 deletions.
6 changes: 3 additions & 3 deletions router/build.sbt
Expand Up @@ -11,7 +11,7 @@ seq(webSettings :_*)
libraryDependencies ++= Seq(
"com.mongodb.casbah" %% "casbah" % "2.1.5-1",
"gov.gds" %% "integration-tools" % "1.4-SNAPSHOT" % "test",
"com.gu" %% "management" % "4.3",
"gov.gds" %% "management" % "5.5-SNAPSHOT",
"org.scalatest" %% "scalatest" % "1.6.1" % "test",
"org.apache.httpcomponents" % "httpclient" % "4.1.2",
"com.google.inject.extensions" % "guice-servlet" % "3.0-rc2",
Expand Down Expand Up @@ -43,9 +43,9 @@ ivyXML := <dependencies>
parallelExecution in Test := false

resolvers ++= Seq(
"GDS maven repo" at "http://alphagov.github.com/maven/snapshots",
"GDS maven repo snapshots" at "http://alphagov.github.com/maven/snapshots",
"GDS maven repo releases" at "http://alphagov.github.com/maven/releases",
"Java.net Maven2 Repository" at "http://download.java.net/maven/2/",
"Guardian Github Releases" at "http://guardian.github.com/maven/repo-releases",
"repo.novus snaps" at "http://repo.novus.com/snapshots/",
"repo.codahale" at "http://repo.codahale.com"
)
47 changes: 30 additions & 17 deletions router/src/main/scala/uk/gov/gds/router/management/management.scala
Expand Up @@ -2,50 +2,63 @@ package uk.gov.gds.router.management

import com.google.inject.Singleton
import com.gu.management._
import com.gu.management.ManagementPage
import com.gu.management.Metric
import request.RequestLoggingFilter
import javax.servlet.http.HttpServletRequest
import uk.gov.gds.router.repository.application.Applications
import uk.gov.gds.router.model.{Route, Application}
import java.util.concurrent.ConcurrentHashMap
import uk.gov.gds.router.util.Logging
import javax.servlet.http.HttpServletRequest

@Singleton
class RouterRequestLoggingFilter extends RequestLoggingFilter(metric = Requests, shouldLogParametersOnNonGetRequests = true)

@Singleton
class RouterManagementFilter extends ManagementFilter {
lazy val pages = List(new ApplicationStatusPage(List(Requests)))
lazy val pages = List(new ApplicationStatusPage, new StatsResetPage)
}

object Requests extends TimingMetric("requests")
object Requests extends TimingMetric("global", "requests", "Incoming router requests", "Incoming router requests")

object ApplicationMetrics {
object ApplicationMetrics extends Logging {

private val metrics = new ConcurrentHashMap[Application, TimingMetric]()

def all = Applications.all.map(timer(_))
def all = Seq(Requests) ++ Applications.all.map(timer(_))

def time[T](route: Route, block: => T) = timer(route.application).measure(block)

private def timer(app: Application) = Option(metrics.get(app)) match {
case Some(metric) => metric
case Some(metric) =>
metric
case None =>
val metric = new TimingMetric(app.id)
val metric = new TimingMetric("application-traffic", app.id, app.id, app.id)
metrics.put(app, metric)
metric
}
}

class ApplicationStatusPage(metrics: Seq[Metric]) extends ManagementPage {
class ApplicationStatusPage extends JsonManagementPage {
val path = "/management/status"

def get(req: HttpServletRequest) = XmlResponse(
<status>
{metrics map {_.toXml}}
<applications>
{ApplicationMetrics.all map { _.toXml }}
</applications>
</status>)
def jsonObj = ApplicationMetrics.all.map(_.asJson)
}

class StatsResetPage extends ManagementPage {
val path = "/management/status/reset"

def get(req: HttpServletRequest) = {
ApplicationMetrics.all.foreach(_.reset())

HtmlResponse(
<html>
<head>
<title>Stats Reset</title>
</head>
<body>
<p>Router stats reset on this node</p>
</body>
</html>
)
}
}

Expand Up @@ -4,9 +4,9 @@ import gov.uk.gds.router.ApplicationsUnderTest
import uk.gov.gds.router.util.JsonSerializer._
import org.scalatest.matchers.ShouldMatchers
import uk.gov.gds.router.model.{Route, Application}
import xml.XML
import uk.gov.gds.router.{MongoDatabaseBackedTest, HttpTestInterface}
import org.apache.http.client.methods.HttpGet
import uk.gov.gds.router.util.JsonSerializer

class RouterIntegrationTest extends MongoDatabaseBackedTest with ShouldMatchers with HttpTestInterface {

Expand Down Expand Up @@ -59,11 +59,11 @@ class RouterIntegrationTest extends MongoDatabaseBackedTest with ShouldMatchers
response.status should be(201)
}

test("Can get headers from response"){
test("Can get headers from response") {
val response = get("/test/set-header")
response.headers.contains(Header("X-Test", "test")) should be(true)
}

test("Can create routes using put") {
val response = put("/routes/route-created-with-put", Map("application_id" -> applicationId, "route_type" -> "full"))
response.status should be(201)
Expand All @@ -78,26 +78,37 @@ class RouterIntegrationTest extends MongoDatabaseBackedTest with ShouldMatchers
}

test("Application metrics are created when application is created") {
val testApplicationMetricts = XML.loadString(get("/management/status").body) \ "applications" \ applicationId
get("/management/status/reset")
val testApplicationMetrics = JsonSerializer.fromJson[List[Map[String, String]]](get("/management/status").body)

(testApplicationMetricts \ "count").text should be("0")
(testApplicationMetricts \ "totalTimeInMillis").text should be("0")
testApplicationMetrics.map {
metric =>
logger.info("Checking metric " + metric("name"))
metric("count") should be("0")
metric("totalTime") should be("0")
}
}

test("Routing GET traffic through an application increments the counter") {
get("/management/status/reset")
get("/route/fulltest/test.html")
val testApplicationMetricts = XML.loadString(get("/management/status").body) \ "applications" \ applicationId

(testApplicationMetricts \ "count").text should be("1")
(testApplicationMetricts \ "totalTimeInMillis").text should not be ("0")
val testApplicationMetrics: List[Map[String, String]] = JsonSerializer.fromJson[List[Map[String, String]]](get("/management/status").body)
val requestCounter = testApplicationMetrics.filter(metric => metric("name") == "requests").head

requestCounter("count") should be("2")
requestCounter("totalTime") should not be ("0")
}

test("Routing POST traffic through an application increments the counter") {
get("/management/status/reset")
post("/route/fulltest/test.html")
val testApplicationMetricts = XML.loadString(get("/management/status").body) \ "applications" \ applicationId

(testApplicationMetricts \ "count").text should be("1")
(testApplicationMetricts \ "totalTimeInMillis").text should not be ("0")
val testApplicationMetrics: List[Map[String, String]] = JsonSerializer.fromJson[List[Map[String, String]]](get("/management/status").body)
val applicationCounter = testApplicationMetrics.filter(_("name") == applicationId).head

applicationCounter("count") should be("1")
applicationCounter("totalTime") should not be ("0")
}

test("canot create route on application that does not exist") {
Expand Down Expand Up @@ -369,7 +380,7 @@ class RouterIntegrationTest extends MongoDatabaseBackedTest with ShouldMatchers
post("/routes/test/outgoing-cookies", Map("application_id" -> applicationId, "route_type" -> "full"))
post("/routes/test/not-modified", Map("application_id" -> applicationId, "route_type" -> "full"))
post("/routes/test/set-header", Map("application_id" -> applicationId, "route_type" -> "full"))

applicationId
}
}

0 comments on commit 17f309f

Please sign in to comment.