Git Product home page Git Product logo

ostrich's Introduction

Ostrich

Build status Codecov branch Project status

Ostrich is a library for scala servers that makes it easy to:

  • load & reload per-environment configuration
  • collect runtime statistics (counters, gauges, metrics, and labels)
  • report those statistics through a simple web interface (optionally with graphs) or into log files
  • interact with the server over HTTP to check build versions or shut it down

The idea is that it should be simple and straightforward, allowing you to plug it in and get started quickly.

Status

This library is deprecated, and users should migrate to Commons Metrics. Please see TwitterServer's migration guide for details.

Building

Use sbt (simple-build-tool) to build:

$ sbt clean update package-dist

The finished jar will be in dist/.

Counters, Gauges, Metrics, and Labels

There are four kinds of statistics that ostrich captures:

  • counters

    A counter is a value that never decreases. Examples might be "widgets_sold" or "births". You just increment the counter each time a countable event happens, and graphing utilities usually graph the deltas over time. To increment a counter, use:

      Stats.incr("births")
    

    or

      Stats.incr("widgets_sold", 5)
    
  • gauges

    A gauge is a value that has a discrete value at any given moment, like "heap_used" or "current_temperature". It's usually a measurement that you only need to take when someone asks. To define a gauge, stick this code somewhere in the server initialization:

      Stats.addGauge("current_temperature") { myThermometer.temperature }
    

    A gauge method must always return a double.

  • metrics

    A metric is tracked via distribution, and is usually used for timings, like so:

      Stats.time("translation") {
        document.translate("de", "en")
      }
    

    But you can also add metrics directly:

      Stats.addMetric("query_results", results.size)
    

    Metrics are collected by tracking the count, min, max, mean (average), and a simple bucket-based histogram of the distribution. This distribution can be used to determine median, 90th percentile, etc.

  • labels

    A label is just a key/value pair of strings, usually used to report a subsystem's state, like "boiler=offline". They're set with:

      Stats.setLabel("boiler", "online")
    

    They have no real statistical value, but can be used to raise flags in logging and monitoring.

RuntimeEnvironment

If you build with standard-project https://github.com/twitter/standard-project, RuntimeEnvironment can pull build and environment info out of the build.properties file that's tucked into your jar. Typical use is to pass your server object (or any object from your jar) and any command-line arguments you haven't already parsed:

val runtime = RuntimeEnvironment(this, args)

The command-line argument parsing is optional, and supports only:

  • --version to print out the jar's build info (name, version, build)

  • -f <filename> to specify a config file manually

  • --validate to validate that your config file can be compiled

Your server object is used as the home jar of the build.properties file. Then the classpath is scanned to find that jar's home and the config files that are located nearby.

Quick Start

A good example server is created by the scala-bootstrapper project here: https://github.com/twitter/scala-bootstrapper

Define a server config class:

class MyServerConfig extends ServerConfig[MyServer] {
  var serverPort: Int = 9999

  def apply(runtime: RuntimeEnvironment) = {
    new MyServer(serverPort)
  }
}

A ServerConfig class contains things you want to configure on your server, as vars, and an apply method that turns a RuntimeEnvironment into your server. ServerConfig is actually a helper for Config that adds logging configuration, sets up the optional admin HTTP server if it was configured, and registers your service with the ServiceTracker so that it will be shutdown when the admin port receives a shutdown command.

Next, make a simple config file for development:

import com.twitter.conversions.time._
import com.twitter.logging.config._
import com.twitter.ostrich.admin.config._
import com.example.config._

new MyServerConfig {
  serverPort = 9999
  admin.httpPort = 9900

  loggers = new LoggerConfig {
    level = Level.INFO
    handlers = new ConsoleHandlerConfig()
  }
}

The config file will be evaluated at runtime by this code in your Main class:

object Main {
  val log = Logger.get(getClass.getName)

  def main(args: Array[String]) {
    val runtime = RuntimeEnvironment(this, args)
    val server = runtime.loadRuntimeConfig[MyServer]()
    log.info("Starting my server!")
    try {
      server.start()
    } catch {
      case e: Exception =>
        e.printStackTrace()
        log.error(e, "Unexpected exception: %s", e.getMessage)
        System.exit(0)
    }
  }
}

Your MyServer class should implement the Service interface so it can be started and shutdown. The runtime environment will find your config file and evaluate it, returning the MyServer object to you so you can start it. And you're set!

Stats API

The base trait of the stats API is StatsProvider, which defines methods for setting and getting each type of collected stat. The concrete implementation is StatsCollection, which stores them all in java concurrent hash maps.

To log or report stats, attach a StatsReporter to a StatsCollection. A StatsReporter keeps its own state, and resets that state each time it reports. You can attach multiple StatsReporters to track independent state without affecting the StatsCollection.

The simplest (and most common) pattern is to use the global singleton named Stats, like so:

import com.twitter.ostrich.stats.Stats

Stats.incr("cache_misses")
Stats.time("memcache_timing") {
  memcache.set(key, value)
}

Stat names can be any string, though conventionally they contain only letters, digits, underline (_), and dash (-), to make it easier for reporting.

You can immediately see any reported stats on the admin web server, if you've activated it, through the "stats" command:

curl localhost:PPPP/stats.txt

(where PPPP is your configured admin port)

ServiceTracker

The global "shutdown" and "quiesce" commands work by talking to a global ServiceTracker object. This is just a set of running Service objects.

Each Service knows how to start and shutdown, so registering a service with the global ServiceTracker will cause it to be shutdown when the server as a whole is shutdown:

ServiceTracker.register(this)

Some helper classes like BackgroundProcess and PeriodicBackgroundProcess implement Service, so they can be used to build simple background tasks that will be automatically shutdown when the server exits.

Admin web service

The easiest way to start the admin service is to construct an AdminServiceConfig with desired configuration, and call apply on it.

To reduce boilerplate in the common case of configuring a server with an admin port and logging, a helper trait called ServerConfig is defined with both:

var loggers: List[LoggerConfig] = Nil
var admin = new AdminServiceConfig()

The apply method on ServerConfig will create and start the admin service if a port is defined, and setup any configured logging.

You can also build an admin service directly from its config:

val adminConfig = new AdminServiceConfig {
  httpPort = 8888
  statsNodes = new StatsConfig {
    reporters = new TimeSeriesCollectorConfig
  }
}
val runtime = RuntimeEnvironment(this, Nil)
val admin = adminConfig()(runtime)

If httpPort isn't set, the admin service won't start, and admin will be None. Otherwise it will be an Option[AdminHttpService].

statsNodes can attach a list of reporters to named stats collections. In the above example, a time-series collector is added to the global Stats object. This is used to provide the web graphs described below under "Web graphs".

Web/socket commands

Commands over the admin interface take the form of an HTTP "get" request:

GET /<command>[/<parameters...>][.<type>]

which can be performed using 'curl' or 'wget':

$ curl http://localhost:PPPP/shutdown

The result body may be json or plain-text, depending on . The default is json, but you can ask for text like so:

$ curl http://localhost:PPPP/stats.txt

For simple commands like shutdown, the response body may simply be the JSON encoding of the string "ok". For others like stats, it may be a nested structure.

The commands are:

  • ping

    Verify that the admin interface is working; server should say "pong" back.

  • reload

    Reload the server config file for any services that support it (most do not).

  • shutdown

    Immediately shutdown the server.

  • quiesce

    Close any listening sockets, stop accepting new connections, and shutdown the server as soon as the last client connection is done.

  • stats

    Dump server statistics as 4 groups: counters, gauges, metrics, and labels.

    • If the period query parameter is specified (e.g. /stats.json?period=10), a StatsListener is acquired for that time period, and all requests with this period value will receive the same stats values throughout that period.
    • Otherwise, if the namespace argument is provided (e.g. /stats.json?namespace=ganglia), a StatsListener is acquired for that namespace, and each request with this namespace value will reset the stats listener, effectively returning the delta since the prior request with that namespace. (See src/scripts/json_stats_fetcher.rb for an example.)
    • If neither period nor namespace parameters are specified, the main stats object will be fetched, returning non-differerential counters and metrics over the life-time of the process.
  • server_info

    Dump server info (server name, version, build, and git revision).

  • threads

    Dump stack traces and stats about each currently running thread.

  • gc

    Force a garbage collection cycle.

Web graphs

If TimeSeriesCollector is attached to a stats collection, the web interface will include a small graph server that can be used to look at the last hour of data on collected stats.

The url

http://localhost:PPPP/graph/

(where PPPP is your admin httpPort) will give a list of currently-collected stats, and links to the current hourly graph for each stat. The graphs are generated in javascript using flot.

Profiling

If you're using heapster, you can generate a profile suitable for reading with google perftools

Example use:

curl -s 'localhost:9990/pprof/heap?pause=10' >| /tmp/prof

This will result in a file that you can be read with pprof

Credits

This started out as several smaller projects that began to overlap so much, we decided to merge them. Major contributers include, in alphabetical order:

  • Alex Payne
  • John Corwin
  • John Kalucki
  • Marius Eriksen
  • Nick Kallen
  • Oliver Gould
  • Pankaj Gupta
  • Robey Pointer
  • Steve Jenson

If you make a significant change, please add your name to the list!

License

This library is released under the Apache Software License, version 2, which should be included with the source in a file named LICENSE.

ostrich's People

Contributors

al3x avatar bdd avatar bwmcadams avatar cacoco avatar dan-cx avatar duncanhills avatar ewhauser avatar gphat avatar grimreaper avatar idarlington avatar imownbey avatar j3h avatar jcrossley avatar johanoskarsson avatar jorgeortiz85 avatar kevinoliver avatar mariusae avatar mosesn avatar nshkrob avatar oxlade39 avatar robey avatar snopoke avatar sprsquish avatar stevegury avatar stevej avatar szegedi avatar travisbrown avatar twilliam avatar vkostyukov avatar wisechengyi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ostrich's Issues

Source code doesn't tally with published binaries.

Hey guys,

The source code doesn't match the functionality published in the binaries. For example, ServerConfig is deprecated with no direct replacement, whilst in the source code there is not even an @deprecated annotation.

Can you push out the latest?

Thanks, Tim

Unresolved dependency problem

Just did git clone & sbt and got this.

[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.markdownj#markdownj;0.3.0-1.0.2b4: not found
[warn] :: org.freemarker#freemarker;2.3.16: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::

Ostrich configuration depends on jarFile presence.

If there's a jar file around, ostrich will look for config files in ./config. If not, it will look in /etc. This means you either have to specify a confgi file manually "-f", or be at the mercy of whether you've cleaned recently or not.

2.12-ification

In order to support 2.12, we need to add crossScalaVersions to Build.scala, and make sure everything compiles. Not every scala library will be built against the current snapshot, so we may have to support different versions from 2.11 to 2.12. If part of an API has churned (scalacheck in particular is susceptible to this) we may need to upgrade the 2.11 library version to make progress. If that happens, contact me (@mosesn) and I'll navigate the upgrade for you–it's a little complicated because we will need to upgrade all of our internal libraries, not just scrooge. Please note that most of this upgrade will not be feasible until we have a portion of util already upgraded.

GraphiteStatsLogger doesn't recover from transient network errors

If a GraphiteStatsLogger has any issues creating the new socket (e.g. connection refused), it will fail and the BackgroundProcess will die.

Expected behavior:
Network issue is caught and logged at the ERROR level, but does not die and tries again on the next period. Graphite statistics need to be more resilient than failing after the first network hiccup.

Test fails

package-dist gives following error.

[info] == com.twitter.ostrich.stats.JsonStatsFetcherSpec ==
INF [20110712-10:54:38.675] admin: Admin HTTP interface started on port 44172.
[error] x json_stats_fetcher.rb should
[error] x work
[error] 'WrappedArray()' doesn't contain 'bugs=1' (JsonStatsFetcherSpec.scala:39)
[info] == com.twitter.ostrich.stats.JsonStatsFetcherSpec ==

Supporting multiple services in config

It appears that Ostrich supports multiple concurrent services, as implied by the need to run ServiceTracker.register(this). However, the documentation only describes creating a configuration for one service. Furthermore, given the typing of runtime.loadRuntimeConfig[Service] it appears that the default loading scheme only supports a single service. While a meta-service can be employed as a work around, it would be useful to either document how to create a more complicated set of services. With that any issues of threading would also be helpful to have documented.

dealphabetize ostrich stats json

Ostrich depends on scala-json, which always produces json with keys in alpha order.
As part of killing scala-json, I am moving Ostrich to use Jackson. It is possible that a consumer of Ostrich has taken a dependency on the fact that its json keys are in alpha order.

Since I don't want to block killing scala-json on deciding/verifying whether it's safe to change this behavior, I've simply had Jackson emit json in alpha order as well.

This ticket is to consider actually deciding/verifying that it's safe to change the alpha behavior remove the sorting.

Feel free to WontFix this. I've mostly just filed this ticket because I thought this was too long to put directly in the code.

One counter value always shows as 1 in the stats page.

I've observed that one particular counter (across various builds) always seems to show its value as "1" no matter how many times it's incremented when I look at the admin page returned by the URL "/stats.txt".

More puzzlingly is that the counter increment is implemented identically to a bunch of others as it is inserted by a macro. On top of this it records the number of entries into a block of code and the counter for successful exits of said block is correct. To check that the incr call was being executed I changed the macro to wrap the call with a println and that shows the value continuously increasing, as it returns the new value of the counter each time.

LatchedStatsListener thread

LatchedStatsListener thread is not running as daemon and therefore blocks the VM from exiting even after AdminHttpService.shutdown() has been called and the main thread has finished. This matters when running the AdminHttpService from an interactive session (such as sbt).

The workaround (or intended solution?) is to call ServiceTracker.shutdown().

Scala 2.9.0.1 build

It would be great to have a Scala 2.9.0.1 build of Ostrich available.

I would love to contribute a patch but I have no experience with sbt so the only JAR I got out of it was missing some class files for unknown reasons.

Can't enable Tracing

I tried using the scala-bootstrapper to set up a server with tracing, but at :PPPP/tracing, it falls through to "Finagle tracing not found!" which seems to signal that ClassLoader is having trouble loading com.twitter.finagle.tracing.Trace which doesn't seem to make much sense.

Sync blocks in Histogram

There are several sync blocks in Ostrich; but the ones that are most troubling are in Histogram, which are used under the covers in the StatsProvider.time* methods. Since these methods are timing function calls and typically shared metrics between threads, this is problematic in that it will cause all threads accessing the metrics to line up on the sync blocks. Is there a way to fix this?

Mention the possible meaning (usage) of internal urls

Besides documenting the standards ostrich commands (that is presented on project description).

ping
reload
shutdown
quiesce
stats
server_info
threads
gc

please mention in more details the possible meaning (usage) of internal urls

/report/
/pprof/heap
/pprof/profile
/pprof/contention
/tracing
/health
/graph/
/graph_data
/quitquitquit
/abortabortabort

It seems that html /report (versus json /stats), health (versus admin /ping), and graph_data may brings additional information for developers / integration.

Unable to open /proc/self/fd

My server stats.txt looks like this:

error processing command: java.lang.InternalError: errno: 13 error: Unable to open directory /proc/self/fd

Local version works fine.

Timeseries graphing doesn't work with slashes in metric names

The way the requests are sent to the server use path.last to get the name of the metric:
https://github.com/twitter/ostrich/blob/master/src/main/scala/com/twitter/ostrich/admin/TimeSeriesCollector.scala#L110

Here's where metrics are created in kestrel:
https://github.com/robey/kestrel/blob/master/src/main/scala/net/lag/kestrel/PersistentQueue.scala#L113

Because of this, the graphs can't be rendered:

DEB [20110906-13:38:32.507] net: GET /graph_data/gauge:q/raw_event/journal_size?p=1,2,5 HTTP/1.1 [500  Internal Server Error] ()
ERR [20110906-13:38:32.507] admin: Exception processing admin http request
ERR [20110906-13:38:32.507] admin: java.util.NoSuchElementException: key not found: journal_size
ERR [20110906-13:38:32.507] admin:     at scala.collection.MapLike$class.default(MapLike.scala:223)
ERR [20110906-13:38:32.507] admin:     at scala.collection.mutable.HashMap.default(HashMap.scala:39)
ERR [20110906-13:38:32.507] admin:     at scala.collection.MapLike$class.apply(MapLike.scala:134)
ERR [20110906-13:38:32.507] admin:     at scala.collection.mutable.HashMap.apply(HashMap.scala:39)
ERR [20110906-13:38:32.507] admin:     at com.twitter.ostrich.admin.TimeSeriesCollector.get(TimeSeriesCollector.scala:87)
ERR [20110906-13:38:32.507] admin:     at com.twitter.ostrich.admin.TimeSeriesCollector$$anon$2.handle(TimeSeriesCollector.scala:110)
ERR [20110906-13:38:32.507] admin:     at com.twitter.ostrich.admin.CgiRequestHandler.handle(AdminHttpService.scala:153)
ERR [20110906-13:38:32.507] admin:     at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
ERR [20110906-13:38:32.507] admin:     at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65)
ERR [20110906-13:38:32.507] admin:     at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68)
ERR [20110906-13:38:32.507] admin:     at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:555)
ERR [20110906-13:38:32.507] admin:     at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
ERR [20110906-13:38:32.507] admin:     at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:527)
ERR [20110906-13:38:32.507] admin:     at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:119)
ERR [20110906-13:38:32.507] admin:     at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:349)
ERR [20110906-13:38:32.507] admin:     at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:321)
ERR [20110906-13:38:32.507] admin:     at java.lang.Thread.run(Thread.java:680)

/cc @robey

Problems with building

I tried to run sbt and got this:

./sbt: line 16: [: za dużo argumentów
[info]
[info] Updating plugins...
[warn] module not found: org.markdownj#markdownj;0.3.0-1.0.2b4
[warn] ==== local: tried
[warn] /home/karol/.ivy2/local/org.markdownj/markdownj/0.3.0-1.0.2b4/ivys/ivy.xml
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] /home/karol/.ivy2/local/org.markdownj/markdownj/0.3.0-1.0.2b4/jars/markdownj.jar
[warn] ==== twitter.com: tried
[warn] http://maven.twttr.com/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.pom
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] http://maven.twttr.com/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.jar
[warn] ==== scala-tools: tried
[warn] http://scala-tools.org/repo-releases/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.pom
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] http://scala-tools.org/repo-releases/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.jar
[warn] ==== freemarker: tried
[warn] http://freemarker.sourceforge.net/maven2/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.pom
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] http://freemarker.sourceforge.net/maven2/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.markdownj#markdownj;0.3.0-1.0.2b4: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[info]
[warn] :: problems summary ::
[warn] :::: WARNINGS
[warn] module not found: org.markdownj#markdownj;0.3.0-1.0.2b4
[warn] ==== local: tried
[warn] /home/karol/.ivy2/local/org.markdownj/markdownj/0.3.0-1.0.2b4/ivys/ivy.xml
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] /home/karol/.ivy2/local/org.markdownj/markdownj/0.3.0-1.0.2b4/jars/markdownj.jar
[warn] ==== twitter.com: tried
[warn] http://maven.twttr.com/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.pom
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] http://maven.twttr.com/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.jar
[warn] ==== scala-tools: tried
[warn] http://scala-tools.org/repo-releases/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.pom
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] http://scala-tools.org/repo-releases/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.jar
[warn] ==== freemarker: tried
[warn] http://freemarker.sourceforge.net/maven2/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.pom
[warn] -- artifact org.markdownj#markdownj;0.3.0-1.0.2b4!markdownj.jar:
[warn] http://freemarker.sourceforge.net/maven2/org/markdownj/markdownj/0.3.0-1.0.2b4/markdownj-0.3.0-1.0.2b4.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.markdownj#markdownj;0.3.0-1.0.2b4: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[info]
[info] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
[error] sbt.ResolveException: unresolved dependency: org.markdownj#markdownj;0.3.0-1.0.2b4: not found
sbt.ResolveException: unresolved dependency: org.markdownj#markdownj;0.3.0-1.0.2b4: not found

Default logging configuration doesn't substituted string formats

Hey,

I'm using ostrich 9.0.4. Not really a show stopper, but when using the AdminHttpService I get log entries pushed to standard out, but without substituted values.

INFO: Admin HTTP interface started on port %d.

Is there any workaround or configuration I can apply to get logging working properly?

Sean

Documents in details the meaning of standard metrics

Some words about percentile may be copied from
https://groups.google.com/forum/?fromgroups=#!topic/finaglers/UCyuoco0dxM

request_latency_ms is a breakdown of how long requests are taking. The stats you asked >about are the latency percentiles in milliseconds. 25% of requests took <= 1ms, 50% took ><= 2ms, 75% <= 8ms, 99.99% <= 95ms. p25 == "25th percentile", p50 == "50th >percentile", etc.

It's good to provide some explanations on finagle client (as probably most used example of metrics exposed via ostrich), finagle server, and common ostrich (JVM) metrics.

COMMON OSTRICH METRICS

counter:jvm_gc_Copy_cycles
counter:jvm_gc_Copy_msec
counter:jvm_gc_MarkSweepCompact_cycles
counter:jvm_gc_MarkSweepCompact_msec
counter:jvm_gc_cycles
counter:jvm_gc_msec
gauge:jvm_heap_committed
gauge:jvm_heap_max
gauge:jvm_heap_used
gauge:jvm_nonheap_committed
gauge:jvm_nonheap_max
gauge:jvm_nonheap_used
gauge:jvm_num_cpus
gauge:jvm_post_gc_Eden_Space_max
gauge:jvm_post_gc_Eden_Space_used
gauge:jvm_post_gc_Perm_Gen_max
gauge:jvm_post_gc_Perm_Gen_used
gauge:jvm_post_gc_Survivor_Space_max
gauge:jvm_post_gc_Survivor_Space_used
gauge:jvm_post_gc_Tenured_Gen_max
gauge:jvm_post_gc_Tenured_Gen_used
gauge:jvm_post_gc_used
gauge:jvm_start_time
gauge:jvm_thread_count
gauge:jvm_thread_daemon_count
gauge:jvm_thread_peak_count
gauge:jvm_uptime

FINAGLE CLIENT METRICS

counter:sampleFinagleThriftClient/closechans
counter:sampleFinagleThriftClient/closed
counter:sampleFinagleThriftClient/closes
counter:sampleFinagleThriftClient/connects
counter:sampleFinagleThriftClient/exn
counter:sampleFinagleThriftClient/exn/java.nio.channels.ClosedChannelException
counter:sampleFinagleThriftClient/failures
counter:sampleFinagleThriftClient/failures/com.twitter.finagle.CancelledRequestException
counter:sampleFinagleThriftClient/received_bytes
counter:sampleFinagleThriftClient/requests
counter:sampleFinagleThriftClient/sent_bytes
counter:sampleFinagleThriftClient/success
gauge:sampleFinagleThriftClient/connections
gauge:sampleFinagleThriftClient/failfast
gauge:sampleFinagleThriftClient/failfast/unhealthy_for_ms
gauge:sampleFinagleThriftClient/failfast/unhealthy_num_tries
gauge:sampleFinagleThriftClient/loadbalancer/size
gauge:sampleFinagleThriftClient/pending
gauge:sampleFinagleThriftClient/pool_size
gauge:sampleFinagleThriftClient/pool_waiters
metric:sampleFinagleThriftClient/codec_connection_preparation_latency_ms
metric:sampleFinagleThriftClient/connect_latency_ms
metric:sampleFinagleThriftClient/connection_duration
metric:sampleFinagleThriftClient/connection_received_bytes
metric:sampleFinagleThriftClient/connection_requests
metric:sampleFinagleThriftClient/connection_sent_bytes
metric:sampleFinagleThriftClient/request_latency_ms

FINAGLE SERVER METRICS

counter:sampleFinagleHttpServer/closechans
counter:sampleFinagleHttpServer/closed
counter:sampleFinagleHttpServer/closes
counter:sampleFinagleHttpServer/connects
counter:sampleFinagleHttpServer/exn/java.nio.channels.ClosedChannelException
counter:sampleFinagleHttpServer/failures/your.other.Exception
counter:sampleFinagleHttpServer/received_bytes
counter:sampleFinagleHttpServer/requests
counter:sampleFinagleHttpServer/sent_bytes
counter:sampleFinagleHttpServer/success
gauge:sampleFinagleHttpServer/connections
gauge:sampleFinagleHttpServer/pending
metric:sampleFinagleHttpServer/connection_duration
metric:sampleFinagleHttpServer/connection_received_bytes
metric:sampleFinagleHttpServer/connection_requests
metric:sampleFinagleHttpServer/connection_sent_bytes
metric:sampleFinagleHttpServer/handletime_us
metric:sampleFinagleHttpServer/request_latency_ms

Some explanations may be copied from
https://groups.google.com/forum/#!msg/finaglers/SCTpQWDvoB8/PMwtCuk1j54J

connections is the current number of connections between client and server
pending is the current number of connections waiting to be processed by finagle
request_concurrency is the current number of connections being processed by finagle
request_queue_size Number of requests waiting to be handled by the server
connection_duration duration of a connection from established to closed?
connection_received_bytes bytes received per connection
connection_requests Number of connection requests that your client did, ie. you can have a pool of 1 connection and the connection can be closed 3 times, so the "connection_requests" would be 4 (even if connections = 1)
connection_sent_bytes bytes send per connection
handletime_us is time to process the response from the server (ie. execute all the chained map/flatMap)
request_latency_ms is the time of everything between request/response.

arguments not a member of com.twitter.ostrich.admin.RuntimeEnvironment

Got the following while compiling searchbird example learning finagle:

[error] /Users/XXXXXXXXX/searchbird/src/main/scala/com/twitter/searchbird/config/SearchbirdServiceConfig.scala:15: value arguments is not a member of com.twitter.ostrich.admin.RuntimeEnvironment
[error] val index = runtime.arguments.get("shard") match {
[error] ^
[error] /Users/XXXXXXXXX/searchbird/src/main/scala/com/twitter/searchbird/config/SearchbirdServiceConfig.scala:17: value toInt is not a member of Any
[error] val which = arg.toInt
[error]

Any ideas how to get around that?

Using Scala 2.8.1/SBT 0.7.4

Ostrich and multiple servers

I'm trying to setup ostrich to run on multiple servers behind a load balancer. Right now I have few ostrich instances running independently. Is there any way to have centralized ostrich server that collects data from clients?

Updating Ostrich to sbt 0.11.0

Hello

I'm working with scala 2.9.1 and sbt 0.11.0. in my project. It is possible to migrate this ostrich version to sbt 0.11.0 ?

Thank you

Published Ostrich 2.9.1 is broken

It is broken and it never worked because it depends on a 2.8.1 version of twitter/scala-json. How is the 2.9.1 version built? I can't see anything in the sources? How did you manage to get the test run under those circumstances?

I'll help with the transition but first we need a 2.9.1 version of json. I added a pull request there twitter-archive/scala-json#1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.