Git Product home page Git Product logo

finch-server's Introduction

finch-server

Finch Server is a library that merges together the great libraries finch, and twitter-server.

Twitter has done a great job of providing great features in twitter-server, but there are some subtleties in utilizing these features, this project aims to make it as easy as possible to use finch and twitter-server together.

Features

Config Flags

All configurable aspects of a finch-server can be configured with command line flags using twitter-utils Flag. The following is a list of flags that are available to configure a finch-server.

The motivation behind using flags is that when running applications on Mesos or in the Cloud, having a self contained task is much better than depending on other resource to configure your app (such as properties/config files). By having all configuration take place with command line flags it becomes trivial to run your server on any host.

-admin.port=:9990                                         : the TCP port for the admin http server
-io.github.benwhitehead.finch.certificatePath=            : Path to PEM format SSL certificate file
-io.github.benwhitehead.finch.httpInterface=:7070         : The TCP Interface and port for the http server {[<hostname/ip>]:port}. (Set to empty value to disable)
-io.github.benwhitehead.finch.httpsInterface=             : The TCP Interface and port for the https server {[<hostname/ip>]:port}. Requires -io.github.benwhitehead.finch.certificatePath and -io.github.benwhitehead.finch.keyPath to be set. (Set to empty value to disable)
-io.github.benwhitehead.finch.keyPath=                    : Path to SSL Key file
-io.github.benwhitehead.finch.maxRequestSize=5            : Max request size (in megabytes)
-io.github.benwhitehead.finch.pidFile=                    : The file to write the pid of the process into
-io.github.benwhitehead.finch.accessLog=access-log        : Whether to add an Access Log Filter, and if so which type [off|access-log{default}|access-log-combined]. Any value other than the listed 3 will be treated as off.

Filters

Route Histograms

Finch Proves a great API for declaring route handlers, finch-server adds a filter to the server to record latency and request count per route and report all metrics to the configured StatsReceiver.

Access Logging

Finch-server can weave a filter into the request chain to provide access logging for all requests to the server. Both traditional and combined formats can be chosen from.

Admin HTTP Server

Twitter-server provides a great AdminHttpServer that can be used to gain insight into how your application is performing, or to provide important administrative tasks (like getting a thread dump from a running server through an Http Interface). There can be some nuance to correctly starting the AdminHttpServer so this is done automatically by finch-server.

SLF4J Logging

By default all twitter libraries use Java Util Logging, finch-server has been configured to use SLF4J for all logging and automatically sets up all SLF4J bridges and re-configures Java Util Logging.

No SLF4J Backed is declared as a dependency, so feel free to pick whichever backend you like. The unit tests however use logback.

An example logback.xml for how to configure access-log file and rolling is available in example-logback.xml in the repo or bundled in the jar.

Usage

finch-server is very easy to use, all you need to create an echo server is the following object. With this object you will now have a full server running your application on port 7070 and the Admin Server on 9990.

Server Object

import io.finch._
import io.github.benwhitehead.finch.FinchServer

object EchoServer extends FinchServer {
  override lazy val serverName = "echo"

  val echo: Endpoint[String] = get("echo" / string) { (phrase: String) =>
    Ok(phrase)
  }

  def service = echo.toService
}

The Endpoint will be boostrapped with all filters and can service requests. For example:

GET /echo/Hello+World HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:17070
User-Agent: HTTPie/0.9.0

HTTP/1.1 200 OK
Content-Length: 11

Hello World

Artifacts

Compiled for scala 2.11

SBT

Artifacts for finch-server are currently hosed in a google storage bucket, so you will need to add a resolver to your sbt config.

resolvers += "finch-server" at "http://storage.googleapis.com/benwhitehead_me/maven/public"

libraryDependencies ++= Seq(
  "io.github.benwhitehead.finch" %% "finch-server" % "0.9.1"
)

finch-server's People

Contributors

benwhitehead avatar

Stargazers

 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

Forkers

pvillega meroveus

finch-server's Issues

Server and route metrics are not being collected correctly

{
  "jvm/classes/current_loaded": 6053,
  "jvm/classes/total_loaded": 6063,
  "jvm/classes/total_unloaded": 0,
  "jvm/compilation/time_msec": 49560,
  "jvm/fd_count": 31,
  "jvm/fd_limit": 4096,
  "jvm/gc/Copy/cycles": 15,
  "jvm/gc/Copy/msec": 2002,
  "jvm/gc/MarkSweepCompact/cycles": 2,
  "jvm/gc/MarkSweepCompact/msec": 451,
  "jvm/gc/cycles": 17,
  "jvm/gc/msec": 2453,
  "jvm/heap/committed": 1038024704,
  "jvm/heap/max": 2075918336,
  "jvm/heap/used": 145065728,
  "jvm/mem/buffer/direct/count": 5,
  "jvm/mem/buffer/direct/max": 198656,
  "jvm/mem/buffer/direct/used": 198656,
  "jvm/mem/buffer/mapped/count": 0,
  "jvm/mem/buffer/mapped/max": 0,
  "jvm/mem/buffer/mapped/used": 0,
  "jvm/mem/current/Code_Cache/max": 50331648,
  "jvm/mem/current/Code_Cache/used": 6184256,
  "jvm/mem/current/Eden_Space/max": 572653568,
  "jvm/mem/current/Eden_Space/used": 28105728,
  "jvm/mem/current/Perm_Gen/max": 85983232,
  "jvm/mem/current/Perm_Gen/used": 35826344,
  "jvm/mem/current/Survivor_Space/max": 71565312,
  "jvm/mem/current/Survivor_Space/used": 919200,
  "jvm/mem/current/Tenured_Gen/max": 1431699456,
  "jvm/mem/current/Tenured_Gen/used": 116040808,
  "jvm/mem/current/used": 187087488,
  "jvm/mem/postGC/Eden_Space/max": 572653568,
  "jvm/mem/postGC/Eden_Space/used": 0,
  "jvm/mem/postGC/Perm_Gen/max": 85983232,
  "jvm/mem/postGC/Perm_Gen/used": 32898992,
  "jvm/mem/postGC/Survivor_Space/max": 71565312,
  "jvm/mem/postGC/Survivor_Space/used": 919200,
  "jvm/mem/postGC/Tenured_Gen/max": 1431699456,
  "jvm/mem/postGC/Tenured_Gen/used": 116040808,
  "jvm/mem/postGC/used": 149859008,
  "jvm/nonheap/committed": 42663936,
  "jvm/nonheap/max": 136314880,
  "jvm/nonheap/used": 41971624,
  "jvm/num_cpus": 1,
  "jvm/postGC/Eden_Space/max": 572653568,
  "jvm/postGC/Eden_Space/used": 0,
  "jvm/postGC/Perm_Gen/max": 85983232,
  "jvm/postGC/Perm_Gen/used": 32898992,
  "jvm/postGC/Survivor_Space/max": 71565312,
  "jvm/postGC/Survivor_Space/used": 919200,
  "jvm/postGC/Tenured_Gen/max": 1431699456,
  "jvm/postGC/Tenured_Gen/used": 116040808,
  "jvm/postGC/used": 149859008,
  "jvm/start_time": 1412142989312,
  "jvm/thread/count": 15,
  "jvm/thread/daemon_count": 13,
  "jvm/thread/peak_count": 15,
  "jvm/uptime": 1512674,
  "scheduler/dispatches": 0,
  "scheduler/productivity": 0.8691284656524658,
  "srv/http/app/closechans": 36,
  "srv/http/app/closed": 36,
  "srv/http/app/closes": 0,
  "srv/http/app/connection_duration.avg": 0,
  "srv/http/app/connection_duration.count": 0,
  "srv/http/app/connection_duration.max": 0,
  "srv/http/app/connection_duration.min": 0,
  "srv/http/app/connection_duration.p50": 0,
  "srv/http/app/connection_duration.p90": 0,
  "srv/http/app/connection_duration.p95": 0,
  "srv/http/app/connection_duration.p99": 0,
  "srv/http/app/connection_duration.p9990": 0,
  "srv/http/app/connection_duration.p9999": 0,
  "srv/http/app/connection_duration.stddev": 0,
  "srv/http/app/connection_duration.sum": 0,
  "srv/http/app/connection_received_bytes.avg": 0,
  "srv/http/app/connection_received_bytes.count": 0,
  "srv/http/app/connection_received_bytes.max": 0,
  "srv/http/app/connection_received_bytes.min": 0,
  "srv/http/app/connection_received_bytes.p50": 0,
  "srv/http/app/connection_received_bytes.p90": 0,
  "srv/http/app/connection_received_bytes.p95": 0,
  "srv/http/app/connection_received_bytes.p99": 0,
  "srv/http/app/connection_received_bytes.p9990": 0,
  "srv/http/app/connection_received_bytes.p9999": 0,
  "srv/http/app/connection_received_bytes.stddev": 0,
  "srv/http/app/connection_received_bytes.sum": 0,
  "srv/http/app/connection_requests.avg": 0,
  "srv/http/app/connection_requests.count": 0,
  "srv/http/app/connection_requests.max": 0,
  "srv/http/app/connection_requests.min": 0,
  "srv/http/app/connection_requests.p50": 0,
  "srv/http/app/connection_requests.p90": 0,
  "srv/http/app/connection_requests.p95": 0,
  "srv/http/app/connection_requests.p99": 0,
  "srv/http/app/connection_requests.p9990": 0,
  "srv/http/app/connection_requests.p9999": 0,
  "srv/http/app/connection_requests.stddev": 0,
  "srv/http/app/connection_requests.sum": 0,
  "srv/http/app/connection_sent_bytes.avg": 0,
  "srv/http/app/connection_sent_bytes.count": 0,
  "srv/http/app/connection_sent_bytes.max": 0,
  "srv/http/app/connection_sent_bytes.min": 0,
  "srv/http/app/connection_sent_bytes.p50": 0,
  "srv/http/app/connection_sent_bytes.p90": 0,
  "srv/http/app/connection_sent_bytes.p95": 0,
  "srv/http/app/connection_sent_bytes.p99": 0,
  "srv/http/app/connection_sent_bytes.p9990": 0,
  "srv/http/app/connection_sent_bytes.p9999": 0,
  "srv/http/app/connection_sent_bytes.stddev": 0,
  "srv/http/app/connection_sent_bytes.sum": 0,
  "srv/http/app/connections": 0,
  "srv/http/app/connects": 36,
  "srv/http/app/handletime_us.avg": 0,
  "srv/http/app/handletime_us.count": 0,
  "srv/http/app/handletime_us.max": 0,
  "srv/http/app/handletime_us.min": 0,
  "srv/http/app/handletime_us.p50": 0,
  "srv/http/app/handletime_us.p90": 0,
  "srv/http/app/handletime_us.p95": 0,
  "srv/http/app/handletime_us.p99": 0,
  "srv/http/app/handletime_us.p9990": 0,
  "srv/http/app/handletime_us.p9999": 0,
  "srv/http/app/handletime_us.stddev": 0,
  "srv/http/app/handletime_us.sum": 0,
  "srv/http/app/load": 0,
  "srv/http/app/pending": 0,
  "srv/http/app/read_timeout": 0,
  "srv/http/app/received_bytes": 112387,
  "srv/http/app/request_latency_ms.avg": 0,
  "srv/http/app/request_latency_ms.count": 0,
  "srv/http/app/request_latency_ms.max": 0,
  "srv/http/app/request_latency_ms.min": 0,
  "srv/http/app/request_latency_ms.p50": 0,
  "srv/http/app/request_latency_ms.p90": 0,
  "srv/http/app/request_latency_ms.p95": 0,
  "srv/http/app/request_latency_ms.p99": 0,
  "srv/http/app/request_latency_ms.p9990": 0,
  "srv/http/app/request_latency_ms.p9999": 0,
  "srv/http/app/request_latency_ms.stddev": 0,
  "srv/http/app/request_latency_ms.sum": 0,
  "srv/http/app/requests": 245,
  "srv/http/app/sent_bytes": 3066264,
  "srv/http/app/socket_unwritable_ms": 0,
  "srv/http/app/socket_writable_ms": 0,
  "srv/http/app/success": 245,
  "srv/http/app/write_timeout": 0,
  "srv/http/closechans": 0,
  "srv/http/closed": 0,
  "srv/http/closes": 0,
  "srv/http/connection_duration.avg": 0,
  "srv/http/connection_duration.count": 0,
  "srv/http/connection_duration.max": 0,
  "srv/http/connection_duration.min": 0,
  "srv/http/connection_duration.p50": 0,
  "srv/http/connection_duration.p90": 0,
  "srv/http/connection_duration.p95": 0,
  "srv/http/connection_duration.p99": 0,
  "srv/http/connection_duration.p9990": 0,
  "srv/http/connection_duration.p9999": 0,
  "srv/http/connection_duration.stddev": 0,
  "srv/http/connection_duration.sum": 0,
  "srv/http/connection_received_bytes.avg": 0,
  "srv/http/connection_received_bytes.count": 0,
  "srv/http/connection_received_bytes.max": 0,
  "srv/http/connection_received_bytes.min": 0,
  "srv/http/connection_received_bytes.p50": 0,
  "srv/http/connection_received_bytes.p90": 0,
  "srv/http/connection_received_bytes.p95": 0,
  "srv/http/connection_received_bytes.p99": 0,
  "srv/http/connection_received_bytes.p9990": 0,
  "srv/http/connection_received_bytes.p9999": 0,
  "srv/http/connection_received_bytes.stddev": 0,
  "srv/http/connection_received_bytes.sum": 0,
  "srv/http/connection_requests.avg": 0,
  "srv/http/connection_requests.count": 0,
  "srv/http/connection_requests.max": 0,
  "srv/http/connection_requests.min": 0,
  "srv/http/connection_requests.p50": 0,
  "srv/http/connection_requests.p90": 0,
  "srv/http/connection_requests.p95": 0,
  "srv/http/connection_requests.p99": 0,
  "srv/http/connection_requests.p9990": 0,
  "srv/http/connection_requests.p9999": 0,
  "srv/http/connection_requests.stddev": 0,
  "srv/http/connection_requests.sum": 0,
  "srv/http/connection_sent_bytes.avg": 0,
  "srv/http/connection_sent_bytes.count": 0,
  "srv/http/connection_sent_bytes.max": 0,
  "srv/http/connection_sent_bytes.min": 0,
  "srv/http/connection_sent_bytes.p50": 0,
  "srv/http/connection_sent_bytes.p90": 0,
  "srv/http/connection_sent_bytes.p95": 0,
  "srv/http/connection_sent_bytes.p99": 0,
  "srv/http/connection_sent_bytes.p9990": 0,
  "srv/http/connection_sent_bytes.p9999": 0,
  "srv/http/connection_sent_bytes.stddev": 0,
  "srv/http/connection_sent_bytes.sum": 0,
  "srv/http/connections": 1,
  "srv/http/connects": 1,
  "srv/http/handletime_us.avg": 0,
  "srv/http/handletime_us.count": 0,
  "srv/http/handletime_us.max": 0,
  "srv/http/handletime_us.min": 0,
  "srv/http/handletime_us.p50": 0,
  "srv/http/handletime_us.p90": 0,
  "srv/http/handletime_us.p95": 0,
  "srv/http/handletime_us.p99": 0,
  "srv/http/handletime_us.p9990": 0,
  "srv/http/handletime_us.p9999": 0,
  "srv/http/handletime_us.stddev": 0,
  "srv/http/handletime_us.sum": 0,
  "srv/http/load": 1,
  "srv/http/pending": 1,
  "srv/http/read_timeout": 0,
  "srv/http/received_bytes": 154,
  "srv/http/request_latency_ms.avg": 0,
  "srv/http/request_latency_ms.count": 0,
  "srv/http/request_latency_ms.max": 0,
  "srv/http/request_latency_ms.min": 0,
  "srv/http/request_latency_ms.p50": 0,
  "srv/http/request_latency_ms.p90": 0,
  "srv/http/request_latency_ms.p95": 0,
  "srv/http/request_latency_ms.p99": 0,
  "srv/http/request_latency_ms.p9990": 0,
  "srv/http/request_latency_ms.p9999": 0,
  "srv/http/request_latency_ms.stddev": 0,
  "srv/http/request_latency_ms.sum": 0,
  "srv/http/requests": 0,
  "srv/http/sent_bytes": 0,
  "srv/http/socket_unwritable_ms": 0,
  "srv/http/socket_writable_ms": 0,
  "srv/http/success": 0,
  "srv/http/write_timeout": 0,
  "zipkin/log_span/error/com.twitter.finagle.ChannelWriteException": 1,
  "zipkin/log_span/ok": 0,
  "zipkin/log_span/try_later": 0,
  "zipkin/log_span/unfinished": 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.