├── .gitignore ├── .travis.yml ├── Godeps ├── Godeps.json ├── Readme └── _workspace │ ├── .gitignore │ └── src │ ├── code.google.com │ └── p │ │ └── gogoprotobuf │ │ └── proto │ │ ├── Makefile │ │ ├── all_test.go │ │ ├── clone.go │ │ ├── clone_test.go │ │ ├── decode.go │ │ ├── decode_gogo.go │ │ ├── encode.go │ │ ├── encode_gogo.go │ │ ├── equal.go │ │ ├── equal_test.go │ │ ├── extensions.go │ │ ├── extensions_gogo.go │ │ ├── extensions_test.go │ │ ├── lib.go │ │ ├── lib_gogo.go │ │ ├── message_set.go │ │ ├── pointer_reflect.go │ │ ├── pointer_unsafe.go │ │ ├── pointer_unsafe_gogo.go │ │ ├── properties.go │ │ ├── properties_gogo.go │ │ ├── size2_test.go │ │ ├── size_test.go │ │ ├── skip_gogo.go │ │ ├── testdata │ │ ├── Makefile │ │ ├── golden_test.go │ │ ├── test.pb.go │ │ ├── test.pb.go.golden │ │ └── test.proto │ │ ├── text.go │ │ ├── text_gogo.go │ │ ├── text_parser.go │ │ ├── text_parser_test.go │ │ └── text_test.go │ └── github.com │ ├── cloudfoundry-incubator │ └── candiedyaml │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── api.go │ │ ├── candiedyaml_suite_test.go │ │ ├── decode.go │ │ ├── decode_test.go │ │ ├── emitter.go │ │ ├── encode.go │ │ ├── encode_test.go │ │ ├── fixtures │ │ └── specification │ │ │ ├── example2_1.yaml │ │ │ ├── example2_10.yaml │ │ │ ├── example2_11.yaml │ │ │ ├── example2_12.yaml │ │ │ ├── example2_13.yaml │ │ │ ├── example2_14.yaml │ │ │ ├── example2_15.yaml │ │ │ ├── example2_15_dumped.yaml │ │ │ ├── example2_16.yaml │ │ │ ├── example2_17.yaml │ │ │ ├── example2_17_control.yaml │ │ │ ├── example2_17_hexesc.yaml │ │ │ ├── example2_17_quoted.yaml │ │ │ ├── example2_17_single.yaml │ │ │ ├── example2_17_tie_fighter.yaml │ │ │ ├── example2_17_unicode.yaml │ │ │ ├── example2_18.yaml │ │ │ ├── example2_19.yaml │ │ │ ├── example2_2.yaml │ │ │ ├── example2_20.yaml │ │ │ ├── example2_21.yaml │ │ │ ├── example2_22.yaml │ │ │ ├── example2_23.yaml │ │ │ ├── example2_23_application.yaml │ │ │ ├── example2_23_non_date.yaml │ │ │ ├── example2_23_picture.yaml │ │ │ ├── example2_24.yaml │ │ │ ├── example2_24_dumped.yaml │ │ │ ├── example2_25.yaml │ │ │ ├── example2_26.yaml │ │ │ ├── example2_27.yaml │ │ │ ├── example2_27_dumped.yaml │ │ │ ├── example2_28.yaml │ │ │ ├── example2_3.yaml │ │ │ ├── example2_4.yaml │ │ │ ├── example2_5.yaml │ │ │ ├── example2_6.yaml │ │ │ ├── example2_7.yaml │ │ │ ├── example2_8.yaml │ │ │ ├── example2_9.yaml │ │ │ ├── example_empty.yaml │ │ │ └── types │ │ │ ├── map.yaml │ │ │ ├── map_mixed_tags.yaml │ │ │ ├── merge.yaml │ │ │ ├── omap.yaml │ │ │ ├── pairs.yaml │ │ │ ├── seq.yaml │ │ │ ├── set.yaml │ │ │ ├── v.yaml │ │ │ └── value.yaml │ │ ├── libyaml-LICENSE │ │ ├── parser.go │ │ ├── parser_test.go │ │ ├── reader.go │ │ ├── reader_test.go │ │ ├── resolver.go │ │ ├── resolver_test.go │ │ ├── run_parser.go │ │ ├── scanner.go │ │ ├── scanner_test.go │ │ ├── tags.go │ │ ├── writer.go │ │ ├── yaml_definesh.go │ │ ├── yaml_privateh.go │ │ └── yamlh.go │ ├── cloudfoundry │ ├── dropsonde │ │ ├── .gitignore │ │ ├── .gitmodules │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── autowire │ │ │ ├── autowire.go │ │ │ ├── autowire_suite_test.go │ │ │ ├── autowire_test.go │ │ │ ├── logs │ │ │ │ ├── logs.go │ │ │ │ ├── logs_suite_test.go │ │ │ │ └── logs_test.go │ │ │ └── metrics │ │ │ │ ├── metrics.go │ │ │ │ ├── metrics_suite_test.go │ │ │ │ └── metrics_test.go │ │ ├── dropsonde_marshaller │ │ │ ├── dropsonde_marshaller.go │ │ │ ├── dropsonde_marshaller_suite_test.go │ │ │ └── dropsonde_marshaller_test.go │ │ ├── dropsonde_suite_test.go │ │ ├── dropsonde_unmarshaller │ │ │ ├── dropsonde_unmarshaller.go │ │ │ ├── dropsonde_unmarshaller_suite_test.go │ │ │ └── dropsonde_unmarshaller_test.go │ │ ├── emitter │ │ │ ├── byte_emitter.go │ │ │ ├── emitter_suite_test.go │ │ │ ├── event_emitter.go │ │ │ ├── event_emitter_test.go │ │ │ ├── event_formatter.go │ │ │ ├── event_formatter_test.go │ │ │ ├── fake │ │ │ │ ├── fake_byte_emitter.go │ │ │ │ └── fake_event_emitter.go │ │ │ ├── heartbeat_emitter.go │ │ │ ├── heartbeat_emitter_test.go │ │ │ ├── instrumented_emitter.go │ │ │ ├── instrumented_emitter_test.go │ │ │ ├── logemitter │ │ │ │ ├── emit.go │ │ │ │ ├── emit_test.go │ │ │ │ ├── emitter_suite_test.go │ │ │ │ └── testhelpers │ │ │ │ │ └── logmessage_testhelper.go │ │ │ ├── udp_emitter.go │ │ │ └── udp_emitter_test.go │ │ ├── events │ │ │ ├── envelope.pb.go │ │ │ ├── envelope_extensions.go │ │ │ ├── envelope_extensions_test.go │ │ │ ├── event.go │ │ │ ├── events_suite_test.go │ │ │ ├── generate-events.sh │ │ │ ├── heartbeat.pb.go │ │ │ ├── http.pb.go │ │ │ ├── log.pb.go │ │ │ └── metric.pb.go │ │ ├── factories │ │ │ ├── factories.go │ │ │ ├── factories_suite_test.go │ │ │ └── factories_test.go │ │ ├── instrumented_handler.go │ │ ├── instrumented_handler_test.go │ │ ├── instrumented_round_tripper.go │ │ ├── instrumented_round_tripper_test.go │ │ ├── integration_test │ │ │ ├── autowire_end_to_end_test.go │ │ │ ├── integration_test_suite_test.go │ │ │ └── package.go │ │ ├── log_sender │ │ │ ├── fake │ │ │ │ └── fake_log_sender.go │ │ │ ├── log_sender.go │ │ │ ├── log_sender_suite_test.go │ │ │ └── log_sender_test.go │ │ ├── metric_sender │ │ │ ├── fake │ │ │ │ └── fake_metric_sender.go │ │ │ ├── metric_sender.go │ │ │ ├── metric_sender_suite_test.go │ │ │ └── metric_sender_test.go │ │ ├── runtime_stats │ │ │ ├── runtime_stats.go │ │ │ ├── runtime_stats_suite_test.go │ │ │ └── runtime_stats_test.go │ │ ├── signature │ │ │ ├── signature_suite_test.go │ │ │ ├── signature_test.go │ │ │ └── signature_verifier.go │ │ └── test │ └── gosteno │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── codec.go │ │ ├── config.go │ │ ├── config_test.go │ │ ├── gosteno-prettify │ │ ├── README.md │ │ └── prettifier.go │ │ ├── io_sink.go │ │ ├── io_sink_test.go │ │ ├── json_codec.go │ │ ├── json_codec_test.go │ │ ├── json_prettifier.go │ │ ├── json_prettifier_test.go │ │ ├── log_level.go │ │ ├── log_level_test.go │ │ ├── logger.go │ │ ├── logger_test.go │ │ ├── null_sink_test.go │ │ ├── perf_test.go │ │ ├── record.go │ │ ├── record_test.go │ │ ├── regexp.go │ │ ├── sink.go │ │ ├── steno.go │ │ ├── steno_test.go │ │ ├── syslog │ │ ├── syslog.go │ │ ├── syslog_test.go │ │ ├── syslog_unix.go │ │ └── syslog_windows.go │ │ ├── syslog_sink.go │ │ ├── syslog_sink_test.go │ │ ├── testing_sink.go │ │ └── testing_sink_test.go │ ├── garyburd │ └── redigo │ │ ├── internal │ │ ├── commandinfo.go │ │ └── redistest │ │ │ └── testdb.go │ │ └── redis │ │ ├── conn.go │ │ ├── conn_test.go │ │ ├── doc.go │ │ ├── log.go │ │ ├── pool.go │ │ ├── pool_test.go │ │ ├── pubsub.go │ │ ├── pubsub_test.go │ │ ├── redis.go │ │ ├── reply.go │ │ ├── reply_test.go │ │ ├── scan.go │ │ ├── scan_test.go │ │ ├── script.go │ │ ├── script_test.go │ │ ├── test_test.go │ │ └── zpop_example_test.go │ ├── nu7hatch │ └── gouuid │ │ ├── .gitignore │ │ ├── COPYING │ │ ├── README.md │ │ ├── example_test.go │ │ ├── uuid.go │ │ └── uuid_test.go │ └── rcrowley │ └── go-metrics │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── cmd │ ├── metrics-bench │ │ └── metrics-bench.go │ ├── metrics-example │ │ └── metrics-example.go │ └── never-read │ │ └── never-read.go │ ├── counter.go │ ├── counter_test.go │ ├── debug.go │ ├── debug_test.go │ ├── ewma.go │ ├── ewma_test.go │ ├── gauge.go │ ├── gauge_float64.go │ ├── gauge_float64_test.go │ ├── gauge_test.go │ ├── graphite.go │ ├── graphite_test.go │ ├── healthcheck.go │ ├── histogram.go │ ├── histogram_test.go │ ├── influxdb │ └── influxdb.go │ ├── json.go │ ├── json_test.go │ ├── librato │ ├── client.go │ └── librato.go │ ├── log.go │ ├── memory.md │ ├── meter.go │ ├── meter_test.go │ ├── metrics.go │ ├── metrics_test.go │ ├── opentsdb.go │ ├── opentsdb_test.go │ ├── registry.go │ ├── registry_test.go │ ├── runtime.go │ ├── runtime_cgo.go │ ├── runtime_no_cgo.go │ ├── runtime_test.go │ ├── sample.go │ ├── sample_test.go │ ├── stathat │ └── stathat.go │ ├── syslog.go │ ├── timer.go │ ├── timer_test.go │ ├── writer.go │ └── writer_test.go ├── README.md ├── access_log ├── access_log_record.go ├── access_logger.go ├── create_running_access_logger.go ├── file_and_loggregator_access_logger.go └── null_access_logger.go ├── common ├── common.go ├── component.go ├── duration.go ├── healthz.go ├── http │ ├── basic_auth.go │ └── headers.go ├── log_counter.go ├── process_status.go ├── spec │ └── component.go └── varz.go ├── config └── config.go ├── example_config └── example.yml ├── main.go ├── proxy ├── proxy.go ├── request_handler.go └── responsewriter.go ├── registry └── registry.go ├── route ├── endpoint.go ├── pool.go └── uris.go ├── router └── router.go ├── stats ├── active_apps.go ├── heap.go └── top_apps.go └── varz └── varz.go /.gitignore: -------------------------------------------------------------------------------- 1 | bin/* 2 | !bin/test 3 | !bin/env 4 | !bin/go 5 | /pkg 6 | *.test 7 | /tmp 8 | *.iml 9 | .idea/ 10 | tags 11 | .DS_Store 12 | *.coverprofile 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.3 4 | - tip 5 | 6 | matrix: 7 | allow_failures: 8 | - go: tip 9 | 10 | install: 11 | - export PATH=$HOME/gopath/bin:$PATH 12 | 13 | script: 14 | - ./scripts/test 15 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/dinp/gorouter", 3 | "GoVersion": "go1.4", 4 | "Deps": [ 5 | { 6 | "ImportPath": "code.google.com/p/gogoprotobuf/proto", 7 | "Rev": "6c980277330804e94257ac7ef70a3adbe1641059" 8 | }, 9 | { 10 | "ImportPath": "github.com/cloudfoundry-incubator/candiedyaml", 11 | "Rev": "39fb5c673e898bc3343f306217f91f485c40a831" 12 | }, 13 | { 14 | "ImportPath": "github.com/cloudfoundry/dropsonde", 15 | "Rev": "510a77a445ec3319a67ad427320de767b0168509" 16 | }, 17 | { 18 | "ImportPath": "github.com/cloudfoundry/gosteno", 19 | "Comment": "scotty_09012012-41-g5c1406e", 20 | "Rev": "5c1406e9ea0ab919f92e1b194169565def41147b" 21 | }, 22 | { 23 | "ImportPath": "github.com/garyburd/redigo/internal", 24 | "Rev": "785e0ca9319196b94fd61abd4c9eab5c11777377" 25 | }, 26 | { 27 | "ImportPath": "github.com/garyburd/redigo/redis", 28 | "Rev": "785e0ca9319196b94fd61abd4c9eab5c11777377" 29 | }, 30 | { 31 | "ImportPath": "github.com/nu7hatch/gouuid", 32 | "Rev": "179d4d0c4d8d407a32af483c2354df1d2c91e6c3" 33 | }, 34 | { 35 | "ImportPath": "github.com/rcrowley/go-metrics", 36 | "Rev": "dc42d45218778850334afa8c0758e3e00ebf6f22" 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/.gitignore: -------------------------------------------------------------------------------- 1 | /pkg 2 | /bin 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # http://code.google.com/p/goprotobuf/ 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | install: 33 | go install 34 | 35 | test: install generate-test-pbs 36 | go test 37 | 38 | 39 | generate-test-pbs: 40 | make install && cd testdata && make 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/extensions_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // http://code.google.com/p/goprotobuf/ 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto_test 33 | 34 | import ( 35 | "testing" 36 | 37 | pb "./testdata" 38 | "code.google.com/p/gogoprotobuf/proto" 39 | ) 40 | 41 | func TestGetExtensionsWithMissingExtensions(t *testing.T) { 42 | msg := &pb.MyMessage{} 43 | ext1 := &pb.Ext{} 44 | if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { 45 | t.Fatalf("Could not set ext1: %s", ext1) 46 | } 47 | exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{ 48 | pb.E_Ext_More, 49 | pb.E_Ext_Text, 50 | }) 51 | if err != nil { 52 | t.Fatalf("GetExtensions() failed: %s", err) 53 | } 54 | if exts[0] != ext1 { 55 | t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0]) 56 | } 57 | if exts[1] != nil { 58 | t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1]) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/lib_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://code.google.com/p/gogoprotobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "encoding/json" 31 | "strconv" 32 | ) 33 | 34 | func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) { 35 | s, ok := m[value] 36 | if !ok { 37 | s = strconv.Itoa(int(value)) 38 | } 39 | return json.Marshal(s) 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/size2_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2012 The Go Authors. All rights reserved. 4 | // http://code.google.com/p/goprotobuf/ 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | import ( 35 | "testing" 36 | ) 37 | 38 | // This is a separate file and package from size_test.go because that one uses 39 | // generated messages and thus may not be in package proto without having a circular 40 | // dependency, whereas this file tests unexported details of size.go. 41 | 42 | func TestVarintSize(t *testing.T) { 43 | // Check the edge cases carefully. 44 | testCases := []struct { 45 | n uint64 46 | size int 47 | }{ 48 | {0, 1}, 49 | {1, 1}, 50 | {127, 1}, 51 | {128, 2}, 52 | {16383, 2}, 53 | {16384, 3}, 54 | {1<<63 - 1, 9}, 55 | {1 << 63, 10}, 56 | } 57 | for _, tc := range testCases { 58 | size := sizeVarint(tc.n) 59 | if size != tc.size { 60 | t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/testdata/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # http://code.google.com/p/goprotobuf/ 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | all: regenerate 33 | 34 | regenerate: 35 | rm -f test.pb.go 36 | protoc --gogo_out=. test.proto 37 | 38 | # The following rules are just aids to development. Not needed for typical testing. 39 | 40 | diff: regenerate 41 | hg diff test.pb.go 42 | 43 | restore: 44 | cp test.pb.go.golden test.pb.go 45 | 46 | preserve: 47 | cp test.pb.go test.pb.go.golden 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/text_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://code.google.com/p/gogoprotobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "fmt" 31 | "reflect" 32 | ) 33 | 34 | func writeEnum(w *textWriter, v reflect.Value, props *Properties) error { 35 | m, ok := enumStringMaps[props.Enum] 36 | if !ok { 37 | if err := writeAny(w, v, props); err != nil { 38 | return err 39 | } 40 | } 41 | key := int32(0) 42 | if v.Kind() == reflect.Ptr { 43 | key = int32(v.Elem().Int()) 44 | } else { 45 | key = int32(v.Int()) 46 | } 47 | s, ok := m[key] 48 | if !ok { 49 | if err := writeAny(w, v, props); err != nil { 50 | return err 51 | } 52 | } 53 | _, err := fmt.Fprint(w, s) 54 | return err 55 | } 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/.gitignore: -------------------------------------------------------------------------------- 1 | *.coverprofile 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.3 5 | 6 | install: 7 | - go get -t -v ./... 8 | - go install github.com/onsi/ginkgo/ginkgo 9 | 10 | script: 11 | - export PATH=$HOME/gopath/bin:$PATH 12 | - ginkgo -r -failOnPending -randomizeAllSpecs -race 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/cloudfoundry-incubator/candiedyaml.svg)](https://travis-ci.org/cloudfoundry-incubator/candiedyaml) 2 | 3 | candiedyaml 4 | =========== 5 | 6 | YAML for Go 7 | 8 | Usage 9 | ----- 10 | 11 | ```go 12 | package myApp 13 | 14 | import ( 15 | "github.com/cloudfoundry-incubator/candiedyaml" 16 | "fmt" 17 | "os" 18 | ) 19 | 20 | func main() { 21 | file, err := os.Open("path/to/some/file.yml") 22 | if err != nil { 23 | println("File does not exist:", err.Error()) 24 | os.Exit(1) 25 | } 26 | 27 | document := new(interface{}) 28 | decoder := candiedyaml.NewDecoder(file) 29 | err = decoder.Decode(document) 30 | 31 | if err != nil { 32 | println("Failed to decode document:", err.Error()) 33 | } 34 | 35 | println("parsed yml into interface:", fmt.Sprintf("%#v", document)) 36 | 37 | fileToWrite, err := os.Create("path/to/some/new/file.yml") 38 | if err != nil { 39 | println("Failed to open file for writing:", err.Error()) 40 | os.Exit(1) 41 | } 42 | 43 | encoder := candiedyaml.NewEncoder(fileToWrite) 44 | err = encoder.Encode(document) 45 | 46 | if err != nil { 47 | println("Failed to encode document:", err.Error()) 48 | os.Exit(1) 49 | } 50 | 51 | return 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/candiedyaml_suite_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | package candiedyaml 16 | 17 | import ( 18 | . "github.com/onsi/ginkgo" 19 | . "github.com/onsi/gomega" 20 | 21 | "testing" 22 | ) 23 | 24 | func TestCandiedyaml(t *testing.T) { 25 | RegisterFailHandler(Fail) 26 | RunSpecs(t, "Candiedyaml Suite") 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_1.yaml: -------------------------------------------------------------------------------- 1 | - Mark McGwire 2 | - Sammy Sosa 3 | - Ken Griffey 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_10.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | hr: 3 | - Mark McGwire 4 | # Following node labeled SS 5 | - &SS Sammy Sosa 6 | rbi: 7 | - *SS # Subsequent occurrence 8 | - Ken Griffey 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_11.yaml: -------------------------------------------------------------------------------- 1 | ? - Detroit Tigers 2 | - Chicago cubs 3 | : 4 | - 2001-07-23 5 | 6 | ? [ New York Yankees, 7 | Atlanta Braves ] 8 | : [ 2001-07-02, 2001-08-12, 9 | 2001-08-14 ] 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_12.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # products purchased 3 | - item : Super Hoop 4 | quantity: 1 5 | - item : Basketball 6 | quantity: 4 7 | - item : Big Shoes 8 | quantity: 1 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_13.yaml: -------------------------------------------------------------------------------- 1 | # ASCII Art 2 | --- | 3 | \//||\/|| 4 | // || ||__ 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_14.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Mark McGwire's 3 | year was crippled 4 | by a knee injury. 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_15.yaml: -------------------------------------------------------------------------------- 1 | > 2 | Sammy Sosa completed another 3 | fine season with great stats. 4 | 5 | 63 Home Runs 6 | 0.288 Batting Average 7 | 8 | What a year! 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_15_dumped.yaml: -------------------------------------------------------------------------------- 1 | > 2 | Sammy Sosa completed another fine season with great stats. 3 | 4 | 63 Home Runs 5 | 0.288 Batting Average 6 | 7 | What a year! -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_16.yaml: -------------------------------------------------------------------------------- 1 | name: Mark McGwire 2 | accomplishment: > 3 | Mark set a major league 4 | home run record in 1998. 5 | stats: | 6 | 65 Home Runs 7 | 0.278 Batting Average 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17.yaml: -------------------------------------------------------------------------------- 1 | unicode: "Sosa did fine.\u263A" 2 | control: "\b1998\t1999\t2000\n" 3 | hexesc: "\x0D\x0A is \r\n" 4 | 5 | single: '"Howdy!" he cried.' 6 | quoted: ' # not a ''comment''.' 7 | tie-fighter: '|\-*-/|' 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17_control.yaml: -------------------------------------------------------------------------------- 1 | control: "\b1998\t1999\t2000\n" 2 | 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17_hexesc.yaml: -------------------------------------------------------------------------------- 1 | hexesc: "\x0D\x0A is \r\n" 2 | 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17_quoted.yaml: -------------------------------------------------------------------------------- 1 | quoted: ' # not a ''comment''.' 2 | 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17_single.yaml: -------------------------------------------------------------------------------- 1 | single: '"Howdy!" he cried.' 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17_tie_fighter.yaml: -------------------------------------------------------------------------------- 1 | tie-fighter: '|\-*-/|' 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_17_unicode.yaml: -------------------------------------------------------------------------------- 1 | unicode: "Sosa did fine.\u263A" 2 | 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_18.yaml: -------------------------------------------------------------------------------- 1 | plain: 2 | This unquoted scalar 3 | spans many lines. 4 | 5 | quoted: "So does this 6 | quoted scalar.\n" 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_19.yaml: -------------------------------------------------------------------------------- 1 | canonical: 12345 2 | decimal: +12_345 3 | sexagesimal: 3:25:45 4 | octal: 014 5 | hexadecimal: 0xC 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_2.yaml: -------------------------------------------------------------------------------- 1 | hr: 65 # Home runs 2 | avg: 0.278 # Batting average 3 | rbi: 147 # Runs Batted In 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_20.yaml: -------------------------------------------------------------------------------- 1 | canonical: 1.23015e+3 2 | exponential: 12.3015e+02 3 | sexagesimal: 20:30.15 4 | fixed: 1_230.15 5 | negative infinity: -.inf 6 | not a number: .NaN 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_21.yaml: -------------------------------------------------------------------------------- 1 | null: ~ 2 | true: yes 3 | false: no 4 | string: '12345' 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_22.yaml: -------------------------------------------------------------------------------- 1 | canonical: 2001-12-15T02:59:43.1Z 2 | iso8601: 2001-12-14t21:59:43.10-05:00 3 | spaced: 2001-12-14 21:59:43.10 -5 4 | date: 2002-12-14 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_23.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | not-date: !!str 2002-04-28 3 | 4 | picture: !!binary "\ 5 | R0lGODlhDAAMAIQAAP//9/X\ 6 | 17unp5WZmZgAAAOfn515eXv\ 7 | Pz7Y6OjuDg4J+fn5OTk6enp\ 8 | 56enmleECcgggoBADs=" 9 | 10 | application specific tag: !something | 11 | The semantics of the tag 12 | above may be different for 13 | different documents. 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_23_application.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | application specific tag: !something | 3 | The semantics of the tag 4 | above may be different for 5 | different documents. 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_23_non_date.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | not-date: !!str 2002-04-28 3 | 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_23_picture.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | picture: !!binary "\ 3 | R0lGODlhDAAMAIQAAP//9/X\ 4 | 17unp5WZmZgAAAOfn515eXv\ 5 | Pz7Y6OjuDg4J+fn5OTk6enp\ 6 | 56enmleECcgggoBADs=" 7 | 8 | 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_24.yaml: -------------------------------------------------------------------------------- 1 | %TAG ! tag:clarkevans.com,2002: 2 | --- !shape 3 | # Use the ! handle for presenting 4 | # tag:clarkevans.com,2002:circle 5 | - !circle 6 | center: &ORIGIN {x: 73, y: 129} 7 | radius: 7 8 | - !line 9 | start: *ORIGIN 10 | finish: { x: 89, y: 102 } 11 | - !label 12 | start: *ORIGIN 13 | color: 0xFFEEBB 14 | text: Pretty vector drawing. 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_24_dumped.yaml: -------------------------------------------------------------------------------- 1 | !shape 2 | - !circle 3 | center: &id001 {x: 73, y: 129} 4 | radius: 7 5 | - !line 6 | finish: {x: 89, y: 102} 7 | start: *id001 8 | - !label 9 | color: 0xFFEEBB 10 | start: *id001 11 | text: Pretty vector drawing. -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_25.yaml: -------------------------------------------------------------------------------- 1 | # sets are represented as a 2 | # mapping where each key is 3 | # associated with the empty string 4 | --- !!set 5 | ? Mark McGwire 6 | ? Sammy Sosa 7 | ? Ken Griff 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_26.yaml: -------------------------------------------------------------------------------- 1 | # ordered maps are represented as 2 | # a sequence of mappings, with 3 | # each mapping having one key 4 | --- !!omap 5 | - Mark McGwire: 65 6 | - Sammy Sosa: 63 7 | - Ken Griffy: 58 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_27.yaml: -------------------------------------------------------------------------------- 1 | --- ! 2 | invoice: 34843 3 | date : 2001-01-23 4 | billTo: &id001 5 | given : Chris 6 | family : Dumars 7 | address: 8 | lines: | 9 | 458 Walkman Dr. 10 | Suite #292 11 | city : Royal Oak 12 | state : MI 13 | postal : 48046 14 | shipTo: *id001 15 | product: 16 | - sku : BL394D 17 | quantity : 4 18 | description : Basketball 19 | price : 450.00 20 | - sku : BL4438H 21 | quantity : 1 22 | description : Super Hoop 23 | price : 2392.00 24 | tax : 251.42 25 | total: 4443.52 26 | comments: 27 | Late afternoon is best. 28 | Backup contact is Nancy 29 | Billsmer @ 338-4338. 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_27_dumped.yaml: -------------------------------------------------------------------------------- 1 | !!org.yaml.snakeyaml.Invoice 2 | billTo: &id001 3 | address: 4 | city: Royal Oak 5 | lines: | 6 | 458 Walkman Dr. 7 | Suite #292 8 | postal: '48046' 9 | state: MI 10 | family: Dumars 11 | given: Chris 12 | comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. 13 | date: '2001-01-23' 14 | invoice: 34843 15 | product: 16 | - {description: Basketball, price: 450.0, quantity: 4, sku: BL394D} 17 | - {description: Super Hoop, price: 2392.0, quantity: 1, sku: BL4438H} 18 | shipTo: *id001 19 | tax: 251.42 20 | total: 4443.52 -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_28.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Time: 2001-11-23 15:01:42 -5 3 | User: ed 4 | Warning: 5 | This is an error message 6 | for the log file 7 | --- 8 | Time: 2001-11-23 15:02:31 -5 9 | User: ed 10 | Warning: 11 | A slightly different error 12 | message. 13 | --- 14 | Date: 2001-11-23 15:03:17 -5 15 | User: ed 16 | Fatal: 17 | Unknown variable "bar" 18 | Stack: 19 | - file: TopClass.py 20 | line: 23 21 | code: | 22 | x = MoreObject("345\n") 23 | - file: MoreClass.py 24 | line: 58 25 | code: |- 26 | foo = bar 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_3.yaml: -------------------------------------------------------------------------------- 1 | american: 2 | - Boston Red Sox 3 | - Detroit Tigers 4 | - New York Yankees 5 | national: 6 | - New York Mets 7 | - Chicago Cubs 8 | - Atlanta Braves -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_4.yaml: -------------------------------------------------------------------------------- 1 | - 2 | name: Mark McGwire 3 | hr: 65 4 | avg: 0.278 5 | - 6 | name: Sammy Sosa 7 | hr: 63 8 | avg: 0.288 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_5.yaml: -------------------------------------------------------------------------------- 1 | - [name , hr, avg ] 2 | - [Mark McGwire, 65, 0.278] 3 | - [Sammy Sosa , 63, 0.288] 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_6.yaml: -------------------------------------------------------------------------------- 1 | Mark McGwire: {hr: 65, avg: 0.278} 2 | Sammy Sosa: { 3 | hr: 63, 4 | avg: 0.288 5 | } 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_7.yaml: -------------------------------------------------------------------------------- 1 | # Ranking of 1998 home runs 2 | --- 3 | - Mark McGwire 4 | - Sammy Sosa 5 | - Ken Griffey 6 | 7 | # Team ranking 8 | --- 9 | - Chicago Cubs 10 | - St Louis Cardinals 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_8.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | time: 20:03:20 3 | player: Sammy Sosa 4 | action: strike (miss) 5 | ... 6 | --- 7 | time: 20:03:47 8 | player: Sammy Sosa 9 | action: grand slam 10 | ... 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example2_9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | hr: # 1998 hr ranking 3 | - Mark McGwire 4 | - Sammy Sosa 5 | rbi: 6 | # 1998 rbi ranking 7 | - Sammy Sosa 8 | - Ken Griffey 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example_empty.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinp/gorouter/8570492fd8d49748ffd6d658d2b7ad0ab959f095/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/example_empty.yaml -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/map.yaml: -------------------------------------------------------------------------------- 1 | # Unordered set of key: value pairs. 2 | Block style: !!map 3 | Clark : Evans 4 | Brian : Ingerson 5 | Oren : Ben-Kiki 6 | Flow style: !!map { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki } 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/map_mixed_tags.yaml: -------------------------------------------------------------------------------- 1 | # Unordered set of key: value pairs. 2 | Block style: ! 3 | Clark : Evans 4 | Brian : Ingerson 5 | Oren : Ben-Kiki 6 | Flow style: { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki } 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/merge.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - &CENTER { x: 1, y: 2 } 3 | - &LEFT { x: 0, y: 2 } 4 | - &BIG { r: 10 } 5 | - &SMALL { r: 1 } 6 | 7 | # All the following maps are equal: 8 | 9 | - # Explicit keys 10 | x: 1 11 | y: 2 12 | r: 10 13 | label: center/big 14 | 15 | - # Merge one map 16 | << : *CENTER 17 | r: 10 18 | label: center/big 19 | 20 | - # Merge multiple maps 21 | << : [ *CENTER, *BIG ] 22 | label: center/big 23 | 24 | - # Override 25 | << : [ *BIG, *LEFT, *SMALL ] 26 | x: 1 27 | label: center/big 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/omap.yaml: -------------------------------------------------------------------------------- 1 | # Explicitly typed ordered map (dictionary). 2 | Bestiary: !!omap 3 | - aardvark: African pig-like ant eater. Ugly. 4 | - anteater: South-American ant eater. Two species. 5 | - anaconda: South-American constrictor snake. Scaly. 6 | # Etc. 7 | # Flow style 8 | Numbers: !!omap [ one: 1, two: 2, three : 3 ] 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/pairs.yaml: -------------------------------------------------------------------------------- 1 | # Explicitly typed pairs. 2 | Block tasks: !!pairs 3 | - meeting: with team. 4 | - meeting: with boss. 5 | - break: lunch. 6 | - meeting: with client. 7 | Flow tasks: !!pairs [ meeting: with team, meeting: with boss ] 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/seq.yaml: -------------------------------------------------------------------------------- 1 | # Ordered sequence of nodes 2 | Block style: !!seq 3 | - Mercury # Rotates - no light/dark sides. 4 | - Venus # Deadliest. Aptly named. 5 | - Earth # Mostly dirt. 6 | - Mars # Seems empty. 7 | - Jupiter # The king. 8 | - Saturn # Pretty. 9 | - Uranus # Where the sun hardly shines. 10 | - Neptune # Boring. No rings. 11 | - Pluto # You call this a planet? 12 | Flow style: !!seq [ Mercury, Venus, Earth, Mars, # Rocks 13 | Jupiter, Saturn, Uranus, Neptune, # Gas 14 | Pluto ] # Overrated 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/set.yaml: -------------------------------------------------------------------------------- 1 | # Explicitly typed set. 2 | baseball players: !!set 3 | ? Mark McGwire 4 | ? Sammy Sosa 5 | ? Ken Griffey 6 | # Flow style 7 | baseball teams: !!set { Boston Red Sox, Detroit Tigers, New York Yankees } 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/v.yaml: -------------------------------------------------------------------------------- 1 | --- # New schema 2 | link with: 3 | - = : library1.dll 4 | version: 1.2 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/fixtures/specification/types/value.yaml: -------------------------------------------------------------------------------- 1 | --- # Old schema 2 | link with: 3 | - library1.dll 4 | - library2.dll 5 | --- # New schema 6 | link with: 7 | - = : library1.dll 8 | version: 1.2 9 | - = : library2.dll 10 | version: 2.3 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/libyaml-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006 Kirill Simonov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/parser_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | package candiedyaml 16 | 17 | import ( 18 | "io/ioutil" 19 | "os" 20 | "path/filepath" 21 | 22 | . "github.com/onsi/ginkgo" 23 | . "github.com/onsi/gomega" 24 | ) 25 | 26 | var parses = func(filename string) { 27 | It("parses "+filename, func() { 28 | file, err := os.Open(filename) 29 | Ω(err).To(BeNil()) 30 | 31 | parser := yaml_parser_t{} 32 | yaml_parser_initialize(&parser) 33 | yaml_parser_set_input_reader(&parser, file) 34 | 35 | failed := false 36 | event := yaml_event_t{} 37 | 38 | for { 39 | if !yaml_parser_parse(&parser, &event) { 40 | failed = true 41 | println("---", parser.error, parser.problem, parser.context, "line", parser.problem_mark.line, "col", parser.problem_mark.column) 42 | break 43 | } 44 | 45 | if event.event_type == yaml_STREAM_END_EVENT { 46 | break 47 | } 48 | } 49 | 50 | file.Close() 51 | 52 | // msg := "SUCCESS" 53 | // if failed { 54 | // msg = "FAILED" 55 | // if parser.error != yaml_NO_ERROR { 56 | // m := parser.problem_mark 57 | // fmt.Printf("ERROR: (%s) %s @ line: %d col: %d\n", 58 | // parser.context, parser.problem, m.line, m.column) 59 | // } 60 | // } 61 | Ω(failed).To(BeFalse()) 62 | }) 63 | } 64 | 65 | var parseYamls = func(dirname string) { 66 | fileInfos, err := ioutil.ReadDir(dirname) 67 | if err != nil { 68 | panic(err.Error()) 69 | } 70 | 71 | for _, fileInfo := range fileInfos { 72 | if !fileInfo.IsDir() { 73 | parses(filepath.Join(dirname, fileInfo.Name())) 74 | } 75 | } 76 | } 77 | 78 | var _ = Describe("Parser", func() { 79 | parseYamls("fixtures/specification") 80 | parseYamls("fixtures/specification/types") 81 | }) 82 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/run_parser.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | package candiedyaml 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | ) 21 | 22 | func Run_parser(cmd string, args []string) { 23 | for i := 0; i < len(args); i++ { 24 | fmt.Printf("[%d] Scanning '%s'", i, args[i]) 25 | file, err := os.Open(args[i]) 26 | if err != nil { 27 | panic(fmt.Sprintf("Invalid file '%s': %s", args[i], err.Error())) 28 | } 29 | 30 | parser := yaml_parser_t{} 31 | yaml_parser_initialize(&parser) 32 | yaml_parser_set_input_reader(&parser, file) 33 | 34 | failed := false 35 | token := yaml_token_t{} 36 | count := 0 37 | for { 38 | if !yaml_parser_scan(&parser, &token) { 39 | failed = true 40 | break 41 | } 42 | 43 | if token.token_type == yaml_STREAM_END_TOKEN { 44 | break 45 | } 46 | count++ 47 | } 48 | 49 | file.Close() 50 | 51 | msg := "SUCCESS" 52 | if failed { 53 | msg = "FAILED" 54 | if parser.error != yaml_NO_ERROR { 55 | m := parser.problem_mark 56 | fmt.Printf("ERROR: (%s) %s @ line: %d col: %d\n", 57 | parser.context, parser.problem, m.line, m.column) 58 | } 59 | } 60 | fmt.Printf("%s (%d tokens)\n", msg, count) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/scanner_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | package candiedyaml 16 | 17 | import ( 18 | "io/ioutil" 19 | "os" 20 | "path/filepath" 21 | 22 | . "github.com/onsi/ginkgo" 23 | . "github.com/onsi/gomega" 24 | ) 25 | 26 | var scan = func(filename string) { 27 | It("scan "+filename, func() { 28 | file, err := os.Open(filename) 29 | Ω(err).To(BeNil()) 30 | 31 | parser := yaml_parser_t{} 32 | yaml_parser_initialize(&parser) 33 | yaml_parser_set_input_reader(&parser, file) 34 | 35 | failed := false 36 | token := yaml_token_t{} 37 | 38 | for { 39 | if !yaml_parser_scan(&parser, &token) { 40 | failed = true 41 | break 42 | } 43 | 44 | if token.token_type == yaml_STREAM_END_TOKEN { 45 | break 46 | } 47 | } 48 | 49 | file.Close() 50 | 51 | // msg := "SUCCESS" 52 | // if failed { 53 | // msg = "FAILED" 54 | // if parser.error != yaml_NO_ERROR { 55 | // m := parser.problem_mark 56 | // fmt.Printf("ERROR: (%s) %s @ line: %d col: %d\n", 57 | // parser.context, parser.problem, m.line, m.column) 58 | // } 59 | // } 60 | Ω(failed).To(BeFalse()) 61 | }) 62 | } 63 | 64 | var scanYamls = func(dirname string) { 65 | fileInfos, err := ioutil.ReadDir(dirname) 66 | if err != nil { 67 | panic(err.Error()) 68 | } 69 | 70 | for _, fileInfo := range fileInfos { 71 | if !fileInfo.IsDir() { 72 | scan(filepath.Join(dirname, fileInfo.Name())) 73 | } 74 | } 75 | } 76 | 77 | var _ = Describe("Scanner", func() { 78 | scanYamls("fixtures/specification") 79 | scanYamls("fixtures/specification/types") 80 | }) 81 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/yaml_definesh.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | package candiedyaml 16 | 17 | const ( 18 | yaml_VERSION_MAJOR = 0 19 | yaml_VERSION_MINOR = 1 20 | yaml_VERSION_PATCH = 6 21 | yaml_VERSION_STRING = "0.1.6" 22 | ) 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.coverprofile 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dropsonde-protocol"] 2 | path = dropsonde-protocol 3 | url = https://github.com/cloudfoundry/dropsonde-protocol 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | notifications: 3 | email: 4 | - cf-lamb@pivotallabs.com 5 | before_install: 6 | - go get code.google.com/p/go.tools/cmd/cover 7 | - go get code.google.com/p/go.tools/cmd/vet 8 | - go get github.com/mattn/goveralls 9 | - go get github.com/onsi/ginkgo/ginkgo 10 | 11 | after_success: 12 | - 'echo "mode: atomic" > all.coverprofile' 13 | - 'find . -name "*.coverprofile" -exec grep -v mode: {} >> all.coverprofile \;' 14 | - PATH=$HOME/gopath/bin:$PATH goveralls -coverprofile=all.coverprofile -repotoken=$COVERALLS_TOKEN 15 | 16 | install: 17 | - go get -d -v -t ./... 18 | 19 | script: PATH=$HOME/gopath/bin:$PATH ./test 20 | 21 | go: 22 | - 1.2.1 23 | - 1.3.1 24 | 25 | matrix: 26 | allow_failures: 27 | - go: tip 28 | 29 | env: 30 | global: 31 | secure: "FjElKYv/qn9DFPYbp/rl41fapRsSvPh7OB0x6T4GZnmDheY6T/oYadHnwp+y5ccDg4nne/IN9+zf46CUpx7RGbjIvy4AeL7L9VS/NlehgWG/tbYFVedXwkruKylqhbbMVrKwsYNBoELnG8SmP1wsvg6mbi1lzf8l1aeufUKQ7nM=" 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/autowire_suite_test.go: -------------------------------------------------------------------------------- 1 | package autowire_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "io/ioutil" 8 | "log" 9 | "testing" 10 | ) 11 | 12 | func TestAutowire(t *testing.T) { 13 | log.SetOutput(ioutil.Discard) 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "Autowire Suite") 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/autowire_test.go: -------------------------------------------------------------------------------- 1 | package autowire_test 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/autowire" 5 | "github.com/cloudfoundry/dropsonde/emitter" 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | "net/http" 9 | "os" 10 | "reflect" 11 | ) 12 | 13 | var _ = Describe("Autowire", func() { 14 | var oldDestination string 15 | var oldOrigin string 16 | 17 | BeforeEach(func() { 18 | oldDestination = os.Getenv("DROPSONDE_DESTINATION") 19 | oldOrigin = os.Getenv("DROPSONDE_ORIGIN") 20 | }) 21 | 22 | AfterEach(func() { 23 | os.Setenv("DROPSONDE_DESTINATION", oldDestination) 24 | os.Setenv("DROPSONDE_ORIGIN", oldOrigin) 25 | }) 26 | 27 | Describe("Initialize", func() { 28 | Context("with a non-nil emitter", func() { 29 | It("instruments the HTTP default transport", func() { 30 | autowire.Initialize(emitter.NewEventEmitter(nil, "")) 31 | Expect(reflect.TypeOf(http.DefaultTransport).Elem().Name()).ToNot(Equal("Transport")) 32 | }) 33 | }) 34 | 35 | Context("with a nil-emitter", func() { 36 | It("resets the HTTP default transport to not be instrumented", func() { 37 | autowire.Initialize(nil) 38 | Expect(reflect.TypeOf(http.DefaultTransport).Elem().Name()).To(Equal("Transport")) 39 | }) 40 | }) 41 | }) 42 | 43 | Describe("CreateDefaultEmitter", func() { 44 | Context("with DROPSONDE_ORIGIN set", func() { 45 | BeforeEach(func() { 46 | os.Setenv("DROPSONDE_ORIGIN", "anything") 47 | }) 48 | 49 | Context("with DROPSONDE_DESTINATION missing", func() { 50 | It("defaults to localhost", func() { 51 | os.Setenv("DROPSONDE_DESTINATION", "") 52 | _, destination := autowire.CreateDefaultEmitter() 53 | 54 | Expect(destination).To(Equal("localhost:3457")) 55 | }) 56 | }) 57 | 58 | Context("with DROPSONDE_DESTINATION set", func() { 59 | It("uses the configured destination", func() { 60 | os.Setenv("DROPSONDE_DESTINATION", "test") 61 | _, destination := autowire.CreateDefaultEmitter() 62 | 63 | Expect(destination).To(Equal("test")) 64 | }) 65 | }) 66 | }) 67 | 68 | Context("with DROPSONDE_ORIGIN missing", func() { 69 | It("returns a nil-emitter", func() { 70 | os.Setenv("DROPSONDE_ORIGIN", "") 71 | emitter, _ := autowire.CreateDefaultEmitter() 72 | Expect(emitter).To(BeNil()) 73 | }) 74 | }) 75 | }) 76 | }) 77 | 78 | type FakeHandler struct{} 79 | 80 | func (fh FakeHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {} 81 | 82 | type FakeRoundTripper struct{} 83 | 84 | func (frt FakeRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { 85 | return nil, nil 86 | } 87 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/logs/logs.go: -------------------------------------------------------------------------------- 1 | // Package logs provides a simple API for sending app logs from STDOUT and STDERR 2 | // through the dropsonde system. 3 | // 4 | // Use 5 | // 6 | // See the documentation for package autowire for details on configuring through 7 | // environment variables. 8 | // 9 | // Import the package (note that you do not need to additionally import 10 | // autowire). The package self-initializes; to send logs use 11 | // 12 | // logs.SendAppLog(appId, message, sourceType, sourceInstance) 13 | // 14 | // for sending errors, 15 | // 16 | // logs.SendAppErrorLog(appId, message, sourceType, sourceInstance) 17 | package logs 18 | 19 | import ( 20 | "github.com/cloudfoundry/dropsonde/autowire" 21 | "github.com/cloudfoundry/dropsonde/log_sender" 22 | "github.com/cloudfoundry/gosteno" 23 | "io" 24 | ) 25 | 26 | var logSender log_sender.LogSender 27 | 28 | func init() { 29 | Initialize(log_sender.NewLogSender(autowire.AutowiredEmitter(), gosteno.NewLogger("autowire/logs"))) 30 | } 31 | 32 | // Initialize prepares the logs package for use with the automatic Emitter 33 | // from dropsonde/autowire. This function is called by the package's init 34 | // method, so should only be explicitly called to reset the default 35 | // LogSender, e.g. in tests. 36 | func Initialize(ls log_sender.LogSender) { 37 | logSender = ls 38 | } 39 | 40 | // SendAppLog sends a log message with the given appid, log message, source type 41 | // and source instance, with a message type of std out. 42 | // Returns an error if one occurs while sending the event. 43 | func SendAppLog(appId, message, sourceType, sourceInstance string) error { 44 | return logSender.SendAppLog(appId, message, sourceType, sourceInstance) 45 | } 46 | 47 | // SendAppErrorLog sends a log error message with the given appid, log message, source type 48 | // and source instance, with a message type of std err. 49 | // Returns an error if one occurs while sending the event. 50 | func SendAppErrorLog(appId, message, sourceType, sourceInstance string) error { 51 | return logSender.SendAppErrorLog(appId, message, sourceType, sourceInstance) 52 | } 53 | 54 | // ScanLogStream sends a log message with the given meta-data for each line from reader. 55 | // Restarts on read errors and continues until EOF (or stopChan is closed). 56 | func ScanLogStream(appId, sourceType, sourceInstance string, reader io.Reader, stopChan chan struct{}) { 57 | logSender.ScanLogStream(appId, sourceType, sourceInstance, reader, stopChan) 58 | } 59 | 60 | // ScanErrorLogStream sends a log error message with the given meta-data for each line from reader. 61 | // Restarts on read errors and continues until EOF (or stopChan is closed). 62 | func ScanErrorLogStream(appId, sourceType, sourceInstance string, reader io.Reader, stopChan chan struct{}) { 63 | logSender.ScanErrorLogStream(appId, sourceType, sourceInstance, reader, stopChan) 64 | } 65 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/logs/logs_suite_test.go: -------------------------------------------------------------------------------- 1 | package logs_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestMetrics(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Logs Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/logs/logs_test.go: -------------------------------------------------------------------------------- 1 | package logs_test 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/autowire/logs" 5 | "github.com/cloudfoundry/dropsonde/log_sender/fake" 6 | 7 | "errors" 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | ) 11 | 12 | var _ = Describe("Logs", func() { 13 | var fakeLogSender *fake.FakeLogSender 14 | 15 | BeforeEach(func() { 16 | fakeLogSender = fake.NewFakeLogSender() 17 | logs.Initialize(fakeLogSender) 18 | }) 19 | 20 | It("delegates SendAppLog", func() { 21 | logs.SendAppLog("app-id", "custom-log-message", "App", "0") 22 | 23 | Expect(fakeLogSender.GetLogs()).To(HaveLen(1)) 24 | Expect(fakeLogSender.GetLogs()[0]).To(Equal(fake.Log{AppId: "app-id", Message: "custom-log-message", SourceType: "App", SourceInstance: "0", MessageType: "OUT"})) 25 | }) 26 | 27 | It("delegates SendAppErrorLog", func() { 28 | logs.SendAppErrorLog("app-id", "custom-log-error-message", "App", "0") 29 | 30 | Expect(fakeLogSender.GetLogs()).To(HaveLen(1)) 31 | Expect(fakeLogSender.GetLogs()[0]).To(Equal(fake.Log{AppId: "app-id", Message: "custom-log-error-message", SourceType: "App", SourceInstance: "0", MessageType: "ERR"})) 32 | }) 33 | 34 | Context("when errors occur", func() { 35 | BeforeEach(func() { 36 | fakeLogSender.ReturnError = errors.New("error occurred") 37 | }) 38 | 39 | It("SendAppLog returns error", func() { 40 | err := logs.SendAppLog("app-id", "custom-log-message", "App", "0") 41 | Expect(err).To(HaveOccurred()) 42 | }) 43 | 44 | It("SendAppErrorLog returns error", func() { 45 | err := logs.SendAppErrorLog("app-id", "custom-log-error-message", "App", "0") 46 | Expect(err).To(HaveOccurred()) 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/metrics/metrics.go: -------------------------------------------------------------------------------- 1 | // Package metrics provides a simple API for sending value and counter metrics 2 | // through the dropsonde system. 3 | // 4 | // Use 5 | // 6 | // See the documentation for package autowire for details on configuring through 7 | // environment variables. 8 | // 9 | // Import the package (note that you do not need to additionally import 10 | // autowire). The package self-initializes; to send metrics use 11 | // 12 | // metrics.SendValue(name, value, unit) 13 | // 14 | // for sending known quantities, and 15 | // 16 | // metrics.IncrementCounter(name) 17 | // 18 | // to increment a counter. (Note that the value of the counter is maintained by 19 | // the receiver of the counter events, not the application that includes this 20 | // package.) 21 | package metrics 22 | 23 | import ( 24 | "github.com/cloudfoundry/dropsonde/autowire" 25 | "github.com/cloudfoundry/dropsonde/metric_sender" 26 | ) 27 | 28 | var metricSender metric_sender.MetricSender 29 | 30 | func init() { 31 | Initialize(metric_sender.NewMetricSender(autowire.AutowiredEmitter())) 32 | } 33 | 34 | // Initialize prepares the metrics package for use with the automatic Emitter 35 | // from dropsonde/autowire. This function is called by the package's init 36 | // method, so should only be explicitly called to reset the default 37 | // MetricSender, e.g. in tests. 38 | func Initialize(ms metric_sender.MetricSender) { 39 | metricSender = ms 40 | } 41 | 42 | // SendValue sends a value event for the named metric. See 43 | // http://metrics20.org/spec/#units for the specifications on allowed units. 44 | func SendValue(name string, value float64, unit string) error { 45 | return metricSender.SendValue(name, value, unit) 46 | } 47 | 48 | // IncrementCounter sends an event to increment the named counter by one. 49 | // Maintaining the value of the counter is the responsibility of the receiver of 50 | // the event, not the process that includes this package. 51 | func IncrementCounter(name string) error { 52 | return metricSender.IncrementCounter(name) 53 | } 54 | 55 | // AddToCounter sends an event to increment the named counter by the specified 56 | // (positive) delta. Maintaining the value of the counter is the responsibility 57 | // of the receiver, as with IncrementCounter. 58 | func AddToCounter(name string, delta uint64) error { 59 | return metricSender.AddToCounter(name, delta) 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/metrics/metrics_suite_test.go: -------------------------------------------------------------------------------- 1 | package metrics_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestMetrics(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Metrics Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/autowire/metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | package metrics_test 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/autowire/metrics" 5 | "github.com/cloudfoundry/dropsonde/metric_sender/fake" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | ) 10 | 11 | var _ = Describe("Metrics", func() { 12 | var fakeMetricSender *fake.FakeMetricSender 13 | 14 | BeforeEach(func() { 15 | fakeMetricSender = fake.NewFakeMetricSender() 16 | metrics.Initialize(fakeMetricSender) 17 | }) 18 | 19 | It("delegates SendValue", func() { 20 | metrics.SendValue("metric", 42.42, "answers") 21 | 22 | Expect(fakeMetricSender.GetValue("metric").Value).To(Equal(42.42)) 23 | Expect(fakeMetricSender.GetValue("metric").Unit).To(Equal("answers")) 24 | }) 25 | 26 | It("delegates IncrementCounter", func() { 27 | metrics.IncrementCounter("count") 28 | 29 | Expect(fakeMetricSender.GetCounter("count")).To(BeEquivalentTo(1)) 30 | 31 | metrics.IncrementCounter("count") 32 | 33 | Expect(fakeMetricSender.GetCounter("count")).To(BeEquivalentTo(2)) 34 | }) 35 | 36 | It("delegates AddToCounter", func() { 37 | metrics.AddToCounter("count", 5) 38 | 39 | Expect(fakeMetricSender.GetCounter("count")).To(BeEquivalentTo(5)) 40 | 41 | metrics.AddToCounter("count", 10) 42 | 43 | Expect(fakeMetricSender.GetCounter("count")).To(BeEquivalentTo(15)) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/dropsonde_marshaller/dropsonde_marshaller_suite_test.go: -------------------------------------------------------------------------------- 1 | package dropsonde_marshaller_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestUnmarshaller(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Dropsonde Marshaller Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/dropsonde_marshaller/dropsonde_marshaller_test.go: -------------------------------------------------------------------------------- 1 | package dropsonde_marshaller_test 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "github.com/cloudfoundry/dropsonde/dropsonde_marshaller" 6 | "github.com/cloudfoundry/dropsonde/events" 7 | "github.com/cloudfoundry/dropsonde/factories" 8 | "github.com/cloudfoundry/loggregatorlib/cfcomponent/instrumentation/testhelpers" 9 | "github.com/cloudfoundry/loggregatorlib/loggertesthelper" 10 | . "github.com/onsi/ginkgo" 11 | . "github.com/onsi/gomega" 12 | ) 13 | 14 | var _ = Describe("DropsondeMarshaller", func() { 15 | var ( 16 | inputChan chan *events.Envelope 17 | outputChan chan []byte 18 | runComplete chan struct{} 19 | marshaller dropsonde_marshaller.DropsondeMarshaller 20 | ) 21 | 22 | BeforeEach(func() { 23 | inputChan = make(chan *events.Envelope, 10) 24 | outputChan = make(chan []byte, 10) 25 | runComplete = make(chan struct{}) 26 | marshaller = dropsonde_marshaller.NewDropsondeMarshaller(loggertesthelper.Logger()) 27 | 28 | go func() { 29 | marshaller.Run(inputChan, outputChan) 30 | close(runComplete) 31 | }() 32 | }) 33 | 34 | AfterEach(func() { 35 | close(inputChan) 36 | Eventually(runComplete).Should(BeClosed()) 37 | }) 38 | 39 | It("marshals envelopes into bytes", func() { 40 | envelope := &events.Envelope{ 41 | Origin: proto.String("fake-origin-3"), 42 | EventType: events.Envelope_Heartbeat.Enum(), 43 | Heartbeat: factories.NewHeartbeat(1, 2, 3), 44 | } 45 | message, _ := proto.Marshal(envelope) 46 | 47 | inputChan <- envelope 48 | outputMessage := <-outputChan 49 | Expect(outputMessage).To(Equal(message)) 50 | }) 51 | 52 | Context("metrics", func() { 53 | It("emits the correct metrics context", func() { 54 | Expect(marshaller.Emit().Name).To(Equal("dropsondeMarshaller")) 55 | }) 56 | 57 | It("emits a heartbeat counter", func() { 58 | envelope := &events.Envelope{ 59 | Origin: proto.String("fake-origin-3"), 60 | EventType: events.Envelope_Heartbeat.Enum(), 61 | Heartbeat: factories.NewHeartbeat(1, 2, 3), 62 | } 63 | 64 | inputChan <- envelope 65 | testhelpers.EventuallyExpectMetric(marshaller, "heartbeatMarshalled", 1) 66 | }) 67 | 68 | It("emits a marshal error counter", func() { 69 | envelope := &events.Envelope{} 70 | 71 | inputChan <- envelope 72 | testhelpers.EventuallyExpectMetric(marshaller, "marshalErrors", 1) 73 | }) 74 | }) 75 | }) 76 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/dropsonde_suite_test.go: -------------------------------------------------------------------------------- 1 | package dropsonde_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "io/ioutil" 8 | "log" 9 | "testing" 10 | ) 11 | 12 | func TestDropsonde(t *testing.T) { 13 | log.SetOutput(ioutil.Discard) 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "Dropsonde Suite") 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/dropsonde_unmarshaller/dropsonde_unmarshaller_suite_test.go: -------------------------------------------------------------------------------- 1 | package dropsonde_unmarshaller_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestUnmarshaller(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Dropsonde Unmarshaller Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/byte_emitter.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | type ByteEmitter interface { 4 | Emit([]byte) error 5 | Close() 6 | } 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/emitter_suite_test.go: -------------------------------------------------------------------------------- 1 | package emitter_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestEmitter(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Emitter Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/event_emitter.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "fmt" 6 | "github.com/cloudfoundry/dropsonde/events" 7 | ) 8 | 9 | type EventEmitter interface { 10 | Emit(events.Event) error 11 | Close() 12 | } 13 | 14 | type eventEmitter struct { 15 | innerEmitter ByteEmitter 16 | origin string 17 | } 18 | 19 | func NewEventEmitter(byteEmitter ByteEmitter, origin string) EventEmitter { 20 | return &eventEmitter{innerEmitter: byteEmitter, origin: origin} 21 | } 22 | 23 | func (e *eventEmitter) Emit(event events.Event) error { 24 | envelope, err := Wrap(event, e.origin) 25 | if err != nil { 26 | return fmt.Errorf("Wrap: %v", err) 27 | } 28 | 29 | data, err := proto.Marshal(envelope) 30 | if err != nil { 31 | return fmt.Errorf("Marshal: %v", err) 32 | } 33 | 34 | return e.innerEmitter.Emit(data) 35 | } 36 | 37 | func (e *eventEmitter) Close() { 38 | e.innerEmitter.Close() 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/event_emitter_test.go: -------------------------------------------------------------------------------- 1 | package emitter_test 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "github.com/cloudfoundry/dropsonde/emitter" 6 | "github.com/cloudfoundry/dropsonde/emitter/fake" 7 | "github.com/cloudfoundry/dropsonde/events" 8 | 9 | "github.com/cloudfoundry/dropsonde/factories" 10 | . "github.com/onsi/ginkgo" 11 | . "github.com/onsi/gomega" 12 | ) 13 | 14 | var _ = Describe("EventEmitter", func() { 15 | Describe("Emit", func() { 16 | Context("without an origin", func() { 17 | It("returns an error", func() { 18 | innerEmitter := fake.NewFakeByteEmitter() 19 | eventEmitter := emitter.NewEventEmitter(innerEmitter, "") 20 | 21 | testEvent := factories.NewHeartbeat(1, 2, 3) 22 | err := eventEmitter.Emit(testEvent) 23 | 24 | Expect(err).To(HaveOccurred()) 25 | Expect(err.Error()).To(ContainSubstring("Wrap: ")) 26 | }) 27 | }) 28 | 29 | It("marshals events and delegates to the inner emitter", func() { 30 | innerEmitter := fake.NewFakeByteEmitter() 31 | origin := "fake-origin" 32 | eventEmitter := emitter.NewEventEmitter(innerEmitter, origin) 33 | 34 | testEvent := factories.NewHeartbeat(1, 2, 3) 35 | err := eventEmitter.Emit(testEvent) 36 | Expect(err).ToNot(HaveOccurred()) 37 | 38 | Expect(innerEmitter.GetMessages()).To(HaveLen(1)) 39 | msg := innerEmitter.GetMessages()[0] 40 | 41 | var envelope events.Envelope 42 | err = proto.Unmarshal(msg, &envelope) 43 | Expect(err).ToNot(HaveOccurred()) 44 | Expect(envelope.GetEventType()).To(Equal(events.Envelope_Heartbeat)) 45 | }) 46 | }) 47 | 48 | Describe("Close", func() { 49 | It("closes the inner emitter", func() { 50 | innerEmitter := fake.NewFakeByteEmitter() 51 | eventEmitter := emitter.NewEventEmitter(innerEmitter, "") 52 | 53 | eventEmitter.Close() 54 | Expect(innerEmitter.IsClosed()).To(BeTrue()) 55 | }) 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/event_formatter.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "errors" 6 | "github.com/cloudfoundry/dropsonde/events" 7 | ) 8 | 9 | var ErrorMissingOrigin = errors.New("Event not emitted due to missing origin information") 10 | var ErrorUnknownEventType = errors.New("Cannot create envelope for unknown event type") 11 | 12 | func Wrap(e events.Event, origin string) (*events.Envelope, error) { 13 | if origin == "" { 14 | return nil, ErrorMissingOrigin 15 | } 16 | 17 | envelope := &events.Envelope{Origin: proto.String(origin)} 18 | 19 | switch e := e.(type) { 20 | case *events.Heartbeat: 21 | envelope.EventType = events.Envelope_Heartbeat.Enum() 22 | envelope.Heartbeat = e 23 | case *events.HttpStart: 24 | envelope.EventType = events.Envelope_HttpStart.Enum() 25 | envelope.HttpStart = e 26 | case *events.HttpStop: 27 | envelope.EventType = events.Envelope_HttpStop.Enum() 28 | envelope.HttpStop = e 29 | case *events.ValueMetric: 30 | envelope.EventType = events.Envelope_ValueMetric.Enum() 31 | envelope.ValueMetric = e 32 | case *events.CounterEvent: 33 | envelope.EventType = events.Envelope_CounterEvent.Enum() 34 | envelope.CounterEvent = e 35 | case *events.LogMessage: 36 | envelope.EventType = events.Envelope_LogMessage.Enum() 37 | envelope.LogMessage = e 38 | default: 39 | return nil, ErrorUnknownEventType 40 | } 41 | 42 | return envelope, nil 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/fake/fake_byte_emitter.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type FakeByteEmitter struct { 8 | ReturnError error 9 | Messages [][]byte 10 | mutex *sync.RWMutex 11 | isClosed bool 12 | } 13 | 14 | func NewFakeByteEmitter() *FakeByteEmitter { 15 | return &FakeByteEmitter{mutex: new(sync.RWMutex)} 16 | } 17 | func (f *FakeByteEmitter) Emit(data []byte) (err error) { 18 | 19 | if f.ReturnError != nil { 20 | err = f.ReturnError 21 | f.ReturnError = nil 22 | return 23 | } 24 | 25 | f.mutex.Lock() 26 | defer f.mutex.Unlock() 27 | 28 | f.Messages = append(f.Messages, data) 29 | return 30 | } 31 | 32 | func (f *FakeByteEmitter) GetMessages() (messages [][]byte) { 33 | f.mutex.Lock() 34 | defer f.mutex.Unlock() 35 | 36 | messages = make([][]byte, len(f.Messages)) 37 | copy(messages, f.Messages) 38 | return 39 | } 40 | 41 | func (f *FakeByteEmitter) Close() { 42 | f.mutex.Lock() 43 | defer f.mutex.Unlock() 44 | f.isClosed = true 45 | } 46 | 47 | func (f *FakeByteEmitter) IsClosed() bool { 48 | f.mutex.RLock() 49 | defer f.mutex.RUnlock() 50 | return f.isClosed 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/fake/fake_event_emitter.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/events" 5 | "sync" 6 | ) 7 | 8 | type envelope struct { 9 | Event events.Event 10 | Origin string 11 | } 12 | 13 | type FakeEventEmitter struct { 14 | ReturnError error 15 | Messages []envelope 16 | mutex *sync.RWMutex 17 | Origin string 18 | isClosed bool 19 | } 20 | 21 | func NewFakeEventEmitter(origin string) *FakeEventEmitter { 22 | return &FakeEventEmitter{mutex: new(sync.RWMutex), Origin: origin} 23 | } 24 | func (f *FakeEventEmitter) Emit(e events.Event) error { 25 | 26 | f.mutex.Lock() 27 | defer f.mutex.Unlock() 28 | 29 | if f.ReturnError != nil { 30 | err := f.ReturnError 31 | f.ReturnError = nil 32 | return err 33 | } 34 | 35 | f.Messages = append(f.Messages, envelope{e, f.Origin}) 36 | return nil 37 | } 38 | 39 | func (f *FakeEventEmitter) GetMessages() (messages []envelope) { 40 | f.mutex.Lock() 41 | defer f.mutex.Unlock() 42 | 43 | messages = make([]envelope, len(f.Messages)) 44 | copy(messages, f.Messages) 45 | return 46 | } 47 | 48 | func (f *FakeEventEmitter) GetEvents() []events.Event { 49 | messages := f.GetMessages() 50 | events := []events.Event{} 51 | for _, msg := range messages { 52 | events = append(events, msg.Event) 53 | } 54 | return events 55 | } 56 | 57 | func (f *FakeEventEmitter) Close() { 58 | f.mutex.Lock() 59 | defer f.mutex.Unlock() 60 | f.isClosed = true 61 | } 62 | 63 | func (f *FakeEventEmitter) IsClosed() bool { 64 | f.mutex.RLock() 65 | defer f.mutex.RUnlock() 66 | return f.isClosed 67 | } 68 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/heartbeat_emitter.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "log" 6 | "os" 7 | "runtime" 8 | "strconv" 9 | "sync" 10 | "time" 11 | ) 12 | 13 | var HeartbeatInterval = 1 * time.Second 14 | 15 | func init() { 16 | intervalOverride, err := strconv.ParseFloat(os.Getenv("DROPSONDE_HEARTBEAT_INTERVAL_SECS"), 64) 17 | if err == nil { 18 | HeartbeatInterval = time.Duration(intervalOverride*1000) * time.Millisecond 19 | } 20 | } 21 | 22 | type heartbeatEmitter struct { 23 | instrumentedEmitter InstrumentedEmitter 24 | innerHbEmitter ByteEmitter 25 | stopChan chan struct{} 26 | origin string 27 | sync.Mutex 28 | closed bool 29 | } 30 | 31 | func NewHeartbeatEmitter(emitter ByteEmitter, origin string) (ByteEmitter, error) { 32 | instrumentedEmitter, err := NewInstrumentedEmitter(emitter) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | hbEmitter := &heartbeatEmitter{ 38 | instrumentedEmitter: instrumentedEmitter, 39 | innerHbEmitter: emitter, 40 | origin: origin, 41 | stopChan: make(chan struct{}), 42 | } 43 | 44 | go hbEmitter.generateHeartbeats(HeartbeatInterval) 45 | runtime.SetFinalizer(hbEmitter, (*heartbeatEmitter).Close) 46 | 47 | return hbEmitter, nil 48 | } 49 | 50 | func (e *heartbeatEmitter) Emit(data []byte) error { 51 | return e.instrumentedEmitter.Emit(data) 52 | } 53 | 54 | func (e *heartbeatEmitter) Close() { 55 | e.Lock() 56 | defer e.Unlock() 57 | 58 | if e.closed { 59 | return 60 | } 61 | 62 | e.closed = true 63 | close(e.stopChan) 64 | } 65 | 66 | func (e *heartbeatEmitter) generateHeartbeats(heartbeatInterval time.Duration) { 67 | defer e.instrumentedEmitter.Close() 68 | 69 | ticker := time.NewTicker(heartbeatInterval) 70 | defer ticker.Stop() 71 | for { 72 | select { 73 | case <-e.stopChan: 74 | return 75 | case <-ticker.C: 76 | hbEvent := e.instrumentedEmitter.GetHeartbeatEvent() 77 | hbEnvelope, err := Wrap(hbEvent, e.origin) 78 | if err != nil { 79 | log.Printf("Failed to wrap heartbeat event: %v\n", err) 80 | break 81 | } 82 | 83 | hbData, err := proto.Marshal(hbEnvelope) 84 | if err != nil { 85 | log.Printf("Failed to marshal heartbeat event: %v\n", err) 86 | break 87 | } 88 | 89 | err = e.innerHbEmitter.Emit(hbData) 90 | if err != nil { 91 | log.Printf("Problem while emitting heartbeat data: %v\n", err) 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/instrumented_emitter.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | import ( 4 | "errors" 5 | "github.com/cloudfoundry/dropsonde/events" 6 | "github.com/cloudfoundry/dropsonde/factories" 7 | "sync" 8 | ) 9 | 10 | type InstrumentedEmitter interface { 11 | ByteEmitter 12 | GetHeartbeatEvent() events.Event 13 | } 14 | 15 | type instrumentedEmitter struct { 16 | wrappedEmitter ByteEmitter 17 | mutex *sync.RWMutex 18 | ReceivedMetricsCounter uint64 19 | SentMetricsCounter uint64 20 | ErrorCounter uint64 21 | } 22 | 23 | func (emitter *instrumentedEmitter) Emit(data []byte) error { 24 | emitter.mutex.Lock() 25 | defer emitter.mutex.Unlock() 26 | emitter.ReceivedMetricsCounter++ 27 | 28 | err := emitter.wrappedEmitter.Emit(data) 29 | if err != nil { 30 | emitter.ErrorCounter++ 31 | } else { 32 | emitter.SentMetricsCounter++ 33 | } 34 | 35 | return err 36 | } 37 | 38 | func NewInstrumentedEmitter(wrappedEmitter ByteEmitter) (InstrumentedEmitter, error) { 39 | if wrappedEmitter == nil { 40 | return nil, errors.New("wrappedEmitter is nil") 41 | } 42 | 43 | emitter := &instrumentedEmitter{wrappedEmitter: wrappedEmitter, mutex: &sync.RWMutex{}} 44 | return emitter, nil 45 | } 46 | 47 | func (emitter *instrumentedEmitter) Close() { 48 | emitter.wrappedEmitter.Close() 49 | } 50 | 51 | func (emitter *instrumentedEmitter) GetHeartbeatEvent() events.Event { 52 | emitter.mutex.Lock() 53 | defer emitter.mutex.Unlock() 54 | 55 | return factories.NewHeartbeat(emitter.SentMetricsCounter, emitter.ReceivedMetricsCounter, emitter.ErrorCounter) 56 | } 57 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/logemitter/emitter_suite_test.go: -------------------------------------------------------------------------------- 1 | package logemitter_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestEmitter(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Log Emitter Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/logemitter/testhelpers/logmessage_testhelper.go: -------------------------------------------------------------------------------- 1 | package testhelpers 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "github.com/cloudfoundry/dropsonde/events" 6 | "time" 7 | ) 8 | 9 | func NewLogMessage(messageString, appId string) *events.LogMessage { 10 | messageType := events.LogMessage_OUT 11 | sourceName := "App" 12 | 13 | return generateLogMessage(messageString, appId, messageType, sourceName, "") 14 | } 15 | 16 | func generateLogMessage(messageString, appId string, messageType events.LogMessage_MessageType, sourceName, sourceId string) *events.LogMessage { 17 | currentTime := time.Now() 18 | logMessage := &events.LogMessage{ 19 | Message: []byte(messageString), 20 | AppId: proto.String(appId), 21 | MessageType: &messageType, 22 | SourceType: proto.String(sourceName), 23 | SourceInstance: proto.String(sourceId), 24 | Timestamp: proto.Int64(currentTime.UnixNano()), 25 | } 26 | 27 | return logMessage 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/emitter/udp_emitter.go: -------------------------------------------------------------------------------- 1 | package emitter 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type udpEmitter struct { 8 | udpAddr *net.UDPAddr 9 | udpConn net.PacketConn 10 | } 11 | 12 | func NewUdpEmitter(remoteAddr string) (*udpEmitter, error) { 13 | addr, err := net.ResolveUDPAddr("udp4", remoteAddr) 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | conn, err := net.ListenPacket("udp4", "") 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | emitter := &udpEmitter{udpAddr: addr, udpConn: conn} 24 | return emitter, nil 25 | } 26 | 27 | func (e *udpEmitter) Emit(data []byte) error { 28 | _, err := e.udpConn.WriteTo(data, e.udpAddr) 29 | return err 30 | } 31 | 32 | func (e *udpEmitter) Close() { 33 | e.udpConn.Close() 34 | } 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/envelope_extensions.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | ) 7 | 8 | const SystemAppId = "system" 9 | 10 | type hasAppId interface { 11 | GetApplicationId() *UUID 12 | } 13 | 14 | func (m *Envelope) GetAppId() string { 15 | if m.GetEventType() == Envelope_LogMessage { 16 | logMessage := m.GetLogMessage() 17 | return logMessage.GetAppId() 18 | } 19 | 20 | var event hasAppId 21 | switch m.GetEventType() { 22 | case Envelope_HttpStart: 23 | event = m.GetHttpStart() 24 | case Envelope_HttpStop: 25 | event = m.GetHttpStop() 26 | case Envelope_HttpStartStop: 27 | event = m.GetHttpStartStop() 28 | default: 29 | return SystemAppId 30 | } 31 | 32 | uuid := event.GetApplicationId() 33 | if uuid != nil { 34 | return uuid.FormattedString() 35 | } 36 | return SystemAppId 37 | } 38 | 39 | func (id *UUID) FormattedString() string { 40 | var u [16]byte 41 | binary.LittleEndian.PutUint64(u[:8], id.GetLow()) 42 | binary.LittleEndian.PutUint64(u[8:], id.GetHigh()) 43 | return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/envelope_extensions_test.go: -------------------------------------------------------------------------------- 1 | package events_test 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/events" 5 | 6 | "code.google.com/p/gogoprotobuf/proto" 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | ) 10 | 11 | var _ = Describe("EnvelopeExtensions", func() { 12 | var testAppUuid = &events.UUID{ 13 | Low: proto.Uint64(1), 14 | High: proto.Uint64(2), 15 | } 16 | 17 | Describe("GetAppId", func() { 18 | Context("HttpStart", func() { 19 | It("returns the App ID if it has one", func() { 20 | envelope := &events.Envelope{ 21 | EventType: events.Envelope_HttpStart.Enum(), 22 | HttpStart: &events.HttpStart{ApplicationId: testAppUuid}, 23 | } 24 | appId := envelope.GetAppId() 25 | Expect(appId).To(Equal("01000000-0000-0000-0200-000000000000")) 26 | }) 27 | 28 | It("returns system app ID if there isn't an App ID", func() { 29 | envelope := &events.Envelope{ 30 | EventType: events.Envelope_HttpStart.Enum(), 31 | HttpStart: &events.HttpStart{}, 32 | } 33 | appId := envelope.GetAppId() 34 | Expect(appId).To(Equal(events.SystemAppId)) 35 | }) 36 | }) 37 | 38 | Context("HttpStop", func() { 39 | It("returns the App ID if it has one", func() { 40 | envelope := &events.Envelope{ 41 | EventType: events.Envelope_HttpStop.Enum(), 42 | HttpStop: &events.HttpStop{ApplicationId: testAppUuid}, 43 | } 44 | appId := envelope.GetAppId() 45 | Expect(appId).To(Equal("01000000-0000-0000-0200-000000000000")) 46 | }) 47 | }) 48 | 49 | Context("HttpStartStop", func() { 50 | It("returns the App ID if it has one", func() { 51 | envelope := &events.Envelope{ 52 | EventType: events.Envelope_HttpStartStop.Enum(), 53 | HttpStartStop: &events.HttpStartStop{ApplicationId: testAppUuid}, 54 | } 55 | appId := envelope.GetAppId() 56 | Expect(appId).To(Equal("01000000-0000-0000-0200-000000000000")) 57 | }) 58 | }) 59 | 60 | Context("LogMessage", func() { 61 | It("returns the App ID ", func() { 62 | envelope := &events.Envelope{ 63 | EventType: events.Envelope_LogMessage.Enum(), 64 | LogMessage: &events.LogMessage{AppId: proto.String("test-app-id")}, 65 | } 66 | appId := envelope.GetAppId() 67 | Expect(appId).To(Equal("test-app-id")) 68 | }) 69 | }) 70 | 71 | Context("Heartbeat", func() { 72 | It("returns the system app ID", func() { 73 | envelope := &events.Envelope{ 74 | EventType: events.Envelope_Heartbeat.Enum(), 75 | } 76 | appId := envelope.GetAppId() 77 | Expect(appId).To(Equal(events.SystemAppId)) 78 | }) 79 | }) 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/event.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type Event interface { 4 | ProtoMessage() 5 | } 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/events_suite_test.go: -------------------------------------------------------------------------------- 1 | package events_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestEvents(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Events Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/generate-events.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | OUT_DIR=`dirname $0` 4 | OUT_DIR=`cd $OUT_DIR && pwd` 5 | 6 | PROTO_DIR=$OUT_DIR/../dropsonde-protocol 7 | 8 | cd $PROTO_DIR 9 | ./generate-go.sh $OUT_DIR -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/heartbeat.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. 2 | // source: heartbeat.proto 3 | // DO NOT EDIT! 4 | 5 | package events 6 | 7 | import proto "code.google.com/p/gogoprotobuf/proto" 8 | import math "math" 9 | 10 | // Reference imports to suppress errors if they are not otherwise used. 11 | var _ = proto.Marshal 12 | var _ = math.Inf 13 | 14 | type Heartbeat struct { 15 | SentCount *uint64 `protobuf:"varint,1,req,name=sentCount" json:"sentCount,omitempty"` 16 | ReceivedCount *uint64 `protobuf:"varint,2,req,name=receivedCount" json:"receivedCount,omitempty"` 17 | ErrorCount *uint64 `protobuf:"varint,3,req,name=errorCount" json:"errorCount,omitempty"` 18 | XXX_unrecognized []byte `json:"-"` 19 | } 20 | 21 | func (m *Heartbeat) Reset() { *m = Heartbeat{} } 22 | func (m *Heartbeat) String() string { return proto.CompactTextString(m) } 23 | func (*Heartbeat) ProtoMessage() {} 24 | 25 | func (m *Heartbeat) GetSentCount() uint64 { 26 | if m != nil && m.SentCount != nil { 27 | return *m.SentCount 28 | } 29 | return 0 30 | } 31 | 32 | func (m *Heartbeat) GetReceivedCount() uint64 { 33 | if m != nil && m.ReceivedCount != nil { 34 | return *m.ReceivedCount 35 | } 36 | return 0 37 | } 38 | 39 | func (m *Heartbeat) GetErrorCount() uint64 { 40 | if m != nil && m.ErrorCount != nil { 41 | return *m.ErrorCount 42 | } 43 | return 0 44 | } 45 | 46 | func init() { 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/events/metric.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. 2 | // source: metric.proto 3 | // DO NOT EDIT! 4 | 5 | package events 6 | 7 | import proto "code.google.com/p/gogoprotobuf/proto" 8 | import math "math" 9 | 10 | // Reference imports to suppress errors if they are not otherwise used. 11 | var _ = proto.Marshal 12 | var _ = math.Inf 13 | 14 | type ValueMetric struct { 15 | Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` 16 | Value *float64 `protobuf:"fixed64,2,req,name=value" json:"value,omitempty"` 17 | Unit *string `protobuf:"bytes,3,req,name=unit" json:"unit,omitempty"` 18 | XXX_unrecognized []byte `json:"-"` 19 | } 20 | 21 | func (m *ValueMetric) Reset() { *m = ValueMetric{} } 22 | func (m *ValueMetric) String() string { return proto.CompactTextString(m) } 23 | func (*ValueMetric) ProtoMessage() {} 24 | 25 | func (m *ValueMetric) GetName() string { 26 | if m != nil && m.Name != nil { 27 | return *m.Name 28 | } 29 | return "" 30 | } 31 | 32 | func (m *ValueMetric) GetValue() float64 { 33 | if m != nil && m.Value != nil { 34 | return *m.Value 35 | } 36 | return 0 37 | } 38 | 39 | func (m *ValueMetric) GetUnit() string { 40 | if m != nil && m.Unit != nil { 41 | return *m.Unit 42 | } 43 | return "" 44 | } 45 | 46 | type CounterEvent struct { 47 | Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` 48 | Delta *uint64 `protobuf:"varint,2,req,name=delta" json:"delta,omitempty"` 49 | XXX_unrecognized []byte `json:"-"` 50 | } 51 | 52 | func (m *CounterEvent) Reset() { *m = CounterEvent{} } 53 | func (m *CounterEvent) String() string { return proto.CompactTextString(m) } 54 | func (*CounterEvent) ProtoMessage() {} 55 | 56 | func (m *CounterEvent) GetName() string { 57 | if m != nil && m.Name != nil { 58 | return *m.Name 59 | } 60 | return "" 61 | } 62 | 63 | func (m *CounterEvent) GetDelta() uint64 { 64 | if m != nil && m.Delta != nil { 65 | return *m.Delta 66 | } 67 | return 0 68 | } 69 | 70 | func init() { 71 | } 72 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/factories/factories.go: -------------------------------------------------------------------------------- 1 | package factories 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "encoding/binary" 6 | "fmt" 7 | "github.com/cloudfoundry/dropsonde/events" 8 | uuid "github.com/nu7hatch/gouuid" 9 | "net/http" 10 | "strconv" 11 | "time" 12 | ) 13 | 14 | func NewUUID(id *uuid.UUID) *events.UUID { 15 | return &events.UUID{Low: proto.Uint64(binary.LittleEndian.Uint64(id[:8])), High: proto.Uint64(binary.LittleEndian.Uint64(id[8:]))} 16 | } 17 | 18 | func NewHttpStart(req *http.Request, peerType events.PeerType, requestId *uuid.UUID) *events.HttpStart { 19 | httpStart := &events.HttpStart{ 20 | Timestamp: proto.Int64(time.Now().UnixNano()), 21 | RequestId: NewUUID(requestId), 22 | PeerType: &peerType, 23 | Method: events.Method(events.Method_value[req.Method]).Enum(), 24 | Uri: proto.String(fmt.Sprintf("%s%s", req.Host, req.URL.Path)), 25 | RemoteAddress: proto.String(req.RemoteAddr), 26 | UserAgent: proto.String(req.UserAgent()), 27 | } 28 | 29 | if applicationId, err := uuid.ParseHex(req.Header.Get("X-CF-ApplicationID")); err == nil { 30 | httpStart.ApplicationId = NewUUID(applicationId) 31 | } 32 | 33 | if instanceIndex, err := strconv.Atoi(req.Header.Get("X-CF-InstanceIndex")); err == nil { 34 | httpStart.InstanceIndex = proto.Int(instanceIndex) 35 | } 36 | 37 | if instanceId := req.Header.Get("X-CF-InstanceID"); instanceId != "" { 38 | httpStart.InstanceId = &instanceId 39 | } 40 | 41 | return httpStart 42 | } 43 | 44 | func NewHttpStop(req *http.Request, statusCode int, contentLength int64, peerType events.PeerType, requestId *uuid.UUID) *events.HttpStop { 45 | httpStop := &events.HttpStop{ 46 | Timestamp: proto.Int64(time.Now().UnixNano()), 47 | Uri: proto.String(fmt.Sprintf("%s%s", req.Host, req.URL.Path)), 48 | RequestId: NewUUID(requestId), 49 | PeerType: &peerType, 50 | StatusCode: proto.Int(statusCode), 51 | ContentLength: proto.Int64(contentLength), 52 | } 53 | 54 | if applicationId, err := uuid.ParseHex(req.Header.Get("X-CF-ApplicationID")); err == nil { 55 | httpStop.ApplicationId = NewUUID(applicationId) 56 | } 57 | 58 | return httpStop 59 | } 60 | 61 | func NewHeartbeat(sentCount, receivedCount, errorCount uint64) *events.Heartbeat { 62 | return &events.Heartbeat{ 63 | SentCount: proto.Uint64(sentCount), 64 | ReceivedCount: proto.Uint64(receivedCount), 65 | ErrorCount: proto.Uint64(errorCount), 66 | } 67 | } 68 | 69 | func NewLogMessage(messageType events.LogMessage_MessageType, messageString, appId, sourceType string) *events.LogMessage { 70 | currentTime := time.Now() 71 | 72 | logMessage := &events.LogMessage{ 73 | Message: []byte(messageString), 74 | AppId: &appId, 75 | MessageType: &messageType, 76 | SourceType: proto.String(sourceType), 77 | Timestamp: proto.Int64(currentTime.UnixNano()), 78 | } 79 | 80 | return logMessage 81 | } 82 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/factories/factories_suite_test.go: -------------------------------------------------------------------------------- 1 | package factories_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestFactories(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Factories Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/instrumented_round_tripper.go: -------------------------------------------------------------------------------- 1 | package dropsonde 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/emitter" 5 | "github.com/cloudfoundry/dropsonde/events" 6 | "github.com/cloudfoundry/dropsonde/factories" 7 | uuid "github.com/nu7hatch/gouuid" 8 | "log" 9 | "net/http" 10 | ) 11 | 12 | type instrumentedRoundTripper struct { 13 | roundTripper http.RoundTripper 14 | emitter emitter.EventEmitter 15 | } 16 | 17 | /* 18 | Helper for creating an InstrumentedRoundTripper which will delegate to the given RoundTripper 19 | */ 20 | func InstrumentedRoundTripper(roundTripper http.RoundTripper, emitter emitter.EventEmitter) http.RoundTripper { 21 | return &instrumentedRoundTripper{roundTripper, emitter} 22 | } 23 | 24 | /* 25 | Wraps the RoundTrip function of the given RoundTripper. 26 | Will provide accounting metrics for the http.Request / http.Response life-cycle 27 | Callers of RoundTrip are responsible for setting the ‘X-CF-RequestID’ field in the request header if they have one. 28 | Callers are also responsible for setting the ‘X-CF-ApplicationID’ and ‘X-CF-InstanceIndex’ fields in the request header if they are known. 29 | */ 30 | func (irt *instrumentedRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { 31 | requestId, err := GenerateUuid() 32 | if err != nil { 33 | log.Printf("failed to generated request ID: %v\n", err) 34 | requestId = &uuid.UUID{} 35 | } 36 | 37 | httpStart := factories.NewHttpStart(req, events.PeerType_Client, requestId) 38 | 39 | parentRequestId, err := uuid.ParseHex(req.Header.Get("X-CF-RequestID")) 40 | if err == nil { 41 | httpStart.ParentRequestId = factories.NewUUID(parentRequestId) 42 | } 43 | 44 | req.Header.Set("X-CF-RequestID", requestId.String()) 45 | 46 | err = irt.emitter.Emit(httpStart) 47 | if err != nil { 48 | log.Printf("failed to emit start event: %v\n", err) 49 | } 50 | 51 | resp, roundTripErr := irt.roundTripper.RoundTrip(req) 52 | 53 | var httpStop *events.HttpStop 54 | if roundTripErr != nil { 55 | httpStop = factories.NewHttpStop(req, 0, 0, events.PeerType_Client, requestId) 56 | } else { 57 | httpStop = factories.NewHttpStop(req, resp.StatusCode, resp.ContentLength, events.PeerType_Client, requestId) 58 | } 59 | 60 | err = irt.emitter.Emit(httpStop) 61 | if err != nil { 62 | log.Printf("failed to emit stop event: %v\n", err) 63 | } 64 | 65 | return resp, roundTripErr 66 | } 67 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/integration_test/integration_test_suite_test.go: -------------------------------------------------------------------------------- 1 | package integration_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "io/ioutil" 8 | "log" 9 | "testing" 10 | ) 11 | 12 | func TestIntegrationTest(t *testing.T) { 13 | log.SetOutput(ioutil.Discard) 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "IntegrationTest Suite") 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/integration_test/package.go: -------------------------------------------------------------------------------- 1 | package integration 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/log_sender/fake/fake_log_sender.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "sync" 7 | ) 8 | 9 | type FakeLogSender struct { 10 | logs []Log 11 | ReturnError error 12 | sync.RWMutex 13 | } 14 | 15 | type Log struct { 16 | AppId string 17 | Message string 18 | SourceType string 19 | SourceInstance string 20 | MessageType string 21 | } 22 | 23 | func NewFakeLogSender() *FakeLogSender { 24 | return &FakeLogSender{} 25 | } 26 | 27 | func (fls *FakeLogSender) SendAppLog(appId, message, sourceType, sourceInstance string) error { 28 | fls.Lock() 29 | defer fls.Unlock() 30 | 31 | if fls.ReturnError != nil { 32 | err := fls.ReturnError 33 | fls.ReturnError = nil 34 | 35 | return err 36 | } 37 | 38 | fls.logs = append(fls.logs, Log{AppId: appId, Message: message, SourceType: sourceType, SourceInstance: sourceInstance, MessageType: "OUT"}) 39 | return nil 40 | } 41 | 42 | func (fls *FakeLogSender) SendAppErrorLog(appId, message, sourceType, sourceInstance string) error { 43 | fls.Lock() 44 | defer fls.Unlock() 45 | 46 | if fls.ReturnError != nil { 47 | err := fls.ReturnError 48 | fls.ReturnError = nil 49 | 50 | return err 51 | } 52 | 53 | fls.logs = append(fls.logs, Log{AppId: appId, Message: message, SourceType: sourceType, SourceInstance: sourceInstance, MessageType: "ERR"}) 54 | return nil 55 | } 56 | 57 | func (fls *FakeLogSender) ScanLogStream(appId, sourceType, sourceInstance string, reader io.Reader, stopChan chan struct{}) { 58 | scanner := bufio.NewScanner(reader) 59 | for scanner.Scan() { 60 | fls.Lock() 61 | msg := scanner.Text() 62 | if len(msg) == 0 { 63 | fls.Unlock() 64 | continue 65 | } 66 | 67 | fls.logs = append(fls.logs, Log{AppId: appId, SourceType: sourceType, SourceInstance: sourceInstance, MessageType: "OUT", Message: msg}) 68 | fls.Unlock() 69 | } 70 | } 71 | 72 | func (fls *FakeLogSender) ScanErrorLogStream(appId, sourceType, sourceInstance string, reader io.Reader, stopChan chan struct{}) { 73 | scanner := bufio.NewScanner(reader) 74 | for scanner.Scan() { 75 | 76 | fls.Lock() 77 | 78 | msg := scanner.Text() 79 | if len(msg) == 0 { 80 | fls.Unlock() 81 | continue 82 | } 83 | 84 | fls.logs = append(fls.logs, Log{AppId: appId, SourceType: sourceType, SourceInstance: sourceInstance, MessageType: "ERR", Message: msg}) 85 | fls.Unlock() 86 | } 87 | } 88 | 89 | func (fls *FakeLogSender) GetLogs() []Log { 90 | fls.Lock() 91 | defer fls.Unlock() 92 | 93 | return fls.logs 94 | } 95 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/log_sender/log_sender_suite_test.go: -------------------------------------------------------------------------------- 1 | package log_sender_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestMetricSender(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "LogSender Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/metric_sender/fake/fake_metric_sender.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import "sync" 4 | 5 | type FakeMetricSender struct { 6 | counters map[string]uint64 7 | values map[string]Metric 8 | sync.RWMutex 9 | } 10 | 11 | type Metric struct { 12 | Value float64 13 | Unit string 14 | } 15 | 16 | func NewFakeMetricSender() *FakeMetricSender { 17 | return &FakeMetricSender{ 18 | counters: make(map[string]uint64), 19 | values: make(map[string]Metric), 20 | } 21 | } 22 | 23 | func (fms *FakeMetricSender) SendValue(name string, value float64, unit string) error { 24 | fms.Lock() 25 | defer fms.Unlock() 26 | fms.values[name] = Metric{Value: value, Unit: unit} 27 | 28 | return nil 29 | } 30 | 31 | func (fms *FakeMetricSender) IncrementCounter(name string) error { 32 | fms.Lock() 33 | defer fms.Unlock() 34 | fms.counters[name]++ 35 | 36 | return nil 37 | } 38 | 39 | func (fms *FakeMetricSender) AddToCounter(name string, delta uint64) error { 40 | fms.Lock() 41 | defer fms.Unlock() 42 | fms.counters[name] = fms.counters[name] + delta 43 | 44 | return nil 45 | } 46 | 47 | func (fms *FakeMetricSender) GetValue(name string) Metric { 48 | fms.RLock() 49 | defer fms.RUnlock() 50 | 51 | return fms.values[name] 52 | } 53 | 54 | func (fms *FakeMetricSender) GetCounter(name string) uint64 { 55 | fms.RLock() 56 | defer fms.RUnlock() 57 | 58 | return fms.counters[name] 59 | } 60 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/metric_sender/metric_sender.go: -------------------------------------------------------------------------------- 1 | package metric_sender 2 | 3 | import ( 4 | "github.com/cloudfoundry/dropsonde/emitter" 5 | "github.com/cloudfoundry/dropsonde/events" 6 | ) 7 | 8 | // A MetricSender emits metric events. 9 | type MetricSender interface { 10 | SendValue(name string, value float64, unit string) error 11 | IncrementCounter(name string) error 12 | AddToCounter(name string, delta uint64) error 13 | } 14 | 15 | type metricSender struct { 16 | eventEmitter emitter.EventEmitter 17 | } 18 | 19 | // NewMetricSender instantiates a metricSender with the given EventEmitter. 20 | func NewMetricSender(eventEmitter emitter.EventEmitter) MetricSender { 21 | return &metricSender{eventEmitter: eventEmitter} 22 | } 23 | 24 | // SendValue sends a metric with the given name, value and unit. See 25 | // http://metrics20.org/spec/#units for a specification of acceptable units. 26 | // Returns an error if one occurs while sending the event. 27 | func (ms *metricSender) SendValue(name string, value float64, unit string) error { 28 | return ms.eventEmitter.Emit(&events.ValueMetric{Name: &name, Value: &value, Unit: &unit}) 29 | } 30 | 31 | // IncrementCounter sends an event to increment the named counter by one. 32 | // Maintaining the value of the counter is the responsibility of the receiver of 33 | // the event, not the process that includes this package. 34 | func (ms *metricSender) IncrementCounter(name string) error { 35 | return ms.AddToCounter(name, 1) 36 | } 37 | 38 | // AddToCounter sends an event to increment the named counter by the specified 39 | // (positive) delta. Maintaining the value of the counter is the responsibility 40 | // of the receiver, as with IncrementCounter. 41 | func (ms *metricSender) AddToCounter(name string, delta uint64) error { 42 | return ms.eventEmitter.Emit(&events.CounterEvent{Name: &name, Delta: &delta}) 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/metric_sender/metric_sender_suite_test.go: -------------------------------------------------------------------------------- 1 | package metric_sender_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestMetricSender(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "MetricSender Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/metric_sender/metric_sender_test.go: -------------------------------------------------------------------------------- 1 | package metric_sender_test 2 | 3 | import ( 4 | "errors" 5 | "github.com/cloudfoundry/dropsonde/emitter/fake" 6 | "github.com/cloudfoundry/dropsonde/events" 7 | "github.com/cloudfoundry/dropsonde/metric_sender" 8 | 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var _ = Describe("MetricSender", func() { 14 | var ( 15 | emitter *fake.FakeEventEmitter 16 | sender metric_sender.MetricSender 17 | ) 18 | 19 | BeforeEach(func() { 20 | emitter = fake.NewFakeEventEmitter("origin") 21 | sender = metric_sender.NewMetricSender(emitter) 22 | }) 23 | 24 | It("sends a metric to its emitter", func() { 25 | err := sender.SendValue("metric-name", 42, "answers") 26 | Expect(err).NotTo(HaveOccurred()) 27 | 28 | Expect(emitter.Messages).To(HaveLen(1)) 29 | metric := emitter.Messages[0].Event.(*events.ValueMetric) 30 | Expect(metric.GetName()).To(Equal("metric-name")) 31 | Expect(metric.GetValue()).To(BeNumerically("==", 42)) 32 | Expect(metric.GetUnit()).To(Equal("answers")) 33 | }) 34 | 35 | It("returns an error if it can't send metric value", func() { 36 | emitter.ReturnError = errors.New("some error") 37 | 38 | err := sender.SendValue("stuff", 12, "no answer") 39 | Expect(emitter.Messages).To(HaveLen(0)) 40 | Expect(err.Error()).To(Equal("some error")) 41 | }) 42 | 43 | It("sends an update counter event to its emitter", func() { 44 | err := sender.IncrementCounter("counter-strike") 45 | Expect(err).NotTo(HaveOccurred()) 46 | 47 | Expect(emitter.Messages).To(HaveLen(1)) 48 | counterEvent := emitter.Messages[0].Event.(*events.CounterEvent) 49 | Expect(counterEvent.GetName()).To(Equal("counter-strike")) 50 | 51 | }) 52 | 53 | It("returns an error if it can't increment counter", func() { 54 | emitter.ReturnError = errors.New("some counter event error") 55 | 56 | err := sender.IncrementCounter("count me in") 57 | Expect(emitter.Messages).To(HaveLen(0)) 58 | Expect(err.Error()).To(Equal("some counter event error")) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/runtime_stats/runtime_stats.go: -------------------------------------------------------------------------------- 1 | package runtime_stats 2 | 3 | import ( 4 | "code.google.com/p/gogoprotobuf/proto" 5 | "github.com/cloudfoundry/dropsonde/emitter" 6 | "github.com/cloudfoundry/dropsonde/events" 7 | "log" 8 | "runtime" 9 | "time" 10 | ) 11 | 12 | type RuntimeStats struct { 13 | eventEmitter emitter.EventEmitter 14 | interval time.Duration 15 | } 16 | 17 | func NewRuntimeStats(eventEmitter emitter.EventEmitter, interval time.Duration) *RuntimeStats { 18 | return &RuntimeStats{ 19 | eventEmitter: eventEmitter, 20 | interval: interval, 21 | } 22 | } 23 | 24 | func (rs *RuntimeStats) Run(stopChan <-chan struct{}) { 25 | ticker := time.NewTicker(rs.interval) 26 | defer ticker.Stop() 27 | for { 28 | rs.emit("numCPUS", float64(runtime.NumCPU())) 29 | rs.emit("numGoRoutines", float64(runtime.NumGoroutine())) 30 | rs.emitMemMetrics() 31 | 32 | select { 33 | case <-ticker.C: 34 | case <-stopChan: 35 | return 36 | } 37 | } 38 | } 39 | 40 | func (rs *RuntimeStats) emitMemMetrics() { 41 | stats := new(runtime.MemStats) 42 | runtime.ReadMemStats(stats) 43 | 44 | rs.emit("memoryStats.numBytesAllocatedHeap", float64(stats.HeapAlloc)) 45 | rs.emit("memoryStats.numBytesAllocatedStack", float64(stats.StackInuse)) 46 | rs.emit("memoryStats.numBytesAllocated", float64(stats.Alloc)) 47 | rs.emit("memoryStats.numMallocs", float64(stats.Mallocs)) 48 | rs.emit("memoryStats.numFrees", float64(stats.Frees)) 49 | rs.emit("memoryStats.lastGCPauseTimeNS", float64(stats.PauseNs[(stats.NumGC+255)%256])) 50 | } 51 | 52 | func (rs *RuntimeStats) emit(name string, value float64) { 53 | err := rs.eventEmitter.Emit(&events.ValueMetric{ 54 | Name: &name, 55 | Value: &value, 56 | Unit: proto.String("count"), 57 | }) 58 | if err != nil { 59 | log.Printf("RuntimeStats: failed to emit: %v", err) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/runtime_stats/runtime_stats_suite_test.go: -------------------------------------------------------------------------------- 1 | package runtime_stats_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestRuntimeStats(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "RuntimeStats Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/signature/signature_suite_test.go: -------------------------------------------------------------------------------- 1 | package signature_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestUnmarshaller(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Signature Suite") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/signature/signature_test.go: -------------------------------------------------------------------------------- 1 | package signature_test 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/sha256" 6 | "github.com/cloudfoundry/dropsonde/signature" 7 | "github.com/cloudfoundry/loggregatorlib/cfcomponent/instrumentation/testhelpers" 8 | "github.com/cloudfoundry/loggregatorlib/loggertesthelper" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var _ = Describe("SignatureVerifier", func() { 14 | var ( 15 | inputChan chan []byte 16 | outputChan chan []byte 17 | runComplete chan struct{} 18 | signatureVerifier signature.SignatureVerifier 19 | ) 20 | 21 | BeforeEach(func() { 22 | inputChan = make(chan []byte, 10) 23 | outputChan = make(chan []byte, 10) 24 | runComplete = make(chan struct{}) 25 | signatureVerifier = signature.NewSignatureVerifier(loggertesthelper.Logger(), "valid-secret") 26 | 27 | go func() { 28 | signatureVerifier.Run(inputChan, outputChan) 29 | close(runComplete) 30 | }() 31 | }) 32 | 33 | AfterEach(func() { 34 | close(inputChan) 35 | Eventually(runComplete).Should(BeClosed()) 36 | }) 37 | 38 | It("discards messages less than 32 bytes long", func() { 39 | message := make([]byte, 1) 40 | inputChan <- message 41 | Consistently(outputChan).ShouldNot(Receive()) 42 | }) 43 | 44 | It("discards messages when verification fails", func() { 45 | message := make([]byte, 33) 46 | inputChan <- message 47 | Consistently(outputChan).ShouldNot(Receive()) 48 | }) 49 | 50 | It("passes through messages with valid signature", func() { 51 | message := []byte{1, 2, 3} 52 | mac := hmac.New(sha256.New, []byte("valid-secret")) 53 | mac.Write(message) 54 | signature := mac.Sum(nil) 55 | 56 | signedMessage := append(signature, message...) 57 | 58 | inputChan <- signedMessage 59 | outputMessage := <-outputChan 60 | Expect(outputMessage).To(Equal(message)) 61 | }) 62 | 63 | Context("metrics", func() { 64 | It("emits the correct metrics context", func() { 65 | Expect(signatureVerifier.Emit().Name).To(Equal("signatureVerifier")) 66 | }) 67 | 68 | It("emits a missing signature error counter", func() { 69 | inputChan <- []byte{1, 2, 3} 70 | testhelpers.EventuallyExpectMetric(signatureVerifier, "missingSignatureErrors", 1) 71 | }) 72 | 73 | It("emits an invalid signature error counter", func() { 74 | inputChan <- make([]byte, 32) 75 | testhelpers.EventuallyExpectMetric(signatureVerifier, "invalidSignatureErrors", 1) 76 | }) 77 | 78 | It("emits an valid signature counter", func() { 79 | message := []byte{1, 2, 3} 80 | mac := hmac.New(sha256.New, []byte("valid-secret")) 81 | mac.Write(message) 82 | signature := mac.Sum(nil) 83 | 84 | signedMessage := append(signature, message...) 85 | inputChan <- signedMessage 86 | testhelpers.EventuallyExpectMetric(signatureVerifier, "validSignatures", 1) 87 | }) 88 | }) 89 | }) 90 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/dropsonde/test: -------------------------------------------------------------------------------- 1 | set -e 2 | cd `dirname $0` 3 | go fmt ./... 4 | go vet ./... 5 | GINKGO="ginkgo -r --race --randomizeAllSpecs --failOnPending --skipMeasurements" 6 | export DROPSONDE_HEARTBEAT_INTERVAL_SECS=0.375 7 | $GINKGO -cover -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | pkg 3 | *.iml 4 | src 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.1 4 | - tip 5 | 6 | matrix: 7 | allow_failures: 8 | - go: tip 9 | 10 | install: 11 | - go get -v launchpad.net/gocheck 12 | - go get -v ./... 13 | - go build -v ./... 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/codec.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | type Codec interface { 4 | EncodeRecord(record *Record) ([]byte, error) 5 | } 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/config.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | type Config struct { 4 | Sinks []Sink 5 | Level LogLevel 6 | Codec Codec 7 | EnableLOC bool 8 | } 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/config_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | . "launchpad.net/gocheck" 5 | ) 6 | 7 | type ConfigSuite struct { 8 | } 9 | 10 | var _ = Suite(&ConfigSuite{}) 11 | 12 | func (s *ConfigSuite) TestReInitLevel(c *C) { 13 | levels := []LogLevel{LOG_INFO, LOG_DEBUG, LOG_WARN} 14 | 15 | for _, level := range levels { 16 | Init(&Config{Level: level}) 17 | 18 | l := NewLogger("reinit") 19 | c.Assert(l.Level(), Equals, level) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/gosteno-prettify/README.md: -------------------------------------------------------------------------------- 1 | # gosteno-prettify 2 | 3 | gosteno-prettify is a command line tool which parses json formatted log lines 4 | from file(s), or stdin, and displays a more human friendly version of each line 5 | to stdout. 6 | 7 | ## Setup 8 | 9 | go get -u github.com/cloudfoundry/gosteno 10 | cd $GOPATH/src/github.com/cloudfoundry/gosteno/gosteno-prettify 11 | go install 12 | 13 | Don't forget to add the $GOPATH/bin to the $PATH 14 | 15 | ## Usage 16 | 17 | gosteno-prettify [OPTS] [FILE(s)] 18 | 19 | Examples : 20 | 21 | gosteno-prettify f - g 22 | Prettify f's contents, then standard input, then g's contents. 23 | 24 | gosteno-prettify 25 | Prettify contents of stdin. 26 | 27 | Fire `gosteno-prettify -h` to see more options. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/io_sink.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "bufio" 5 | "os" 6 | "sync" 7 | ) 8 | 9 | type IOSink struct { 10 | writer *bufio.Writer 11 | codec Codec 12 | file *os.File 13 | 14 | sync.Mutex 15 | } 16 | 17 | func NewIOSink(file *os.File) *IOSink { 18 | writer := bufio.NewWriter(file) 19 | 20 | x := new(IOSink) 21 | x.writer = writer 22 | x.file = file 23 | 24 | return x 25 | } 26 | 27 | func NewFileSink(path string) *IOSink { 28 | file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) 29 | if err != nil { 30 | panic(err) 31 | } 32 | 33 | return NewIOSink(file) 34 | } 35 | 36 | func (x *IOSink) AddRecord(record *Record) { 37 | bytes, _ := x.codec.EncodeRecord(record) 38 | 39 | x.Lock() 40 | defer x.Unlock() 41 | 42 | x.writer.Write(bytes) 43 | 44 | // Need to append a newline for IO sink 45 | x.writer.WriteString("\n") 46 | } 47 | 48 | func (x *IOSink) Flush() { 49 | x.Lock() 50 | defer x.Unlock() 51 | 52 | x.writer.Flush() 53 | } 54 | 55 | func (x *IOSink) SetCodec(codec Codec) { 56 | x.Lock() 57 | defer x.Unlock() 58 | 59 | x.codec = codec 60 | } 61 | 62 | func (x *IOSink) GetCodec() Codec { 63 | x.Lock() 64 | defer x.Unlock() 65 | 66 | return x.codec 67 | } 68 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/io_sink_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | . "launchpad.net/gocheck" 7 | ) 8 | 9 | type IOSinkSuite struct { 10 | } 11 | 12 | var _ = Suite(&IOSinkSuite{}) 13 | 14 | func (s *IOSinkSuite) TestAddRecord(c *C) { 15 | pReader, pWriter := io.Pipe() 16 | sink := NewIOSink(nil) 17 | sink.writer = bufio.NewWriter(pWriter) 18 | sink.SetCodec(NewJsonCodec()) 19 | 20 | go func(msg string) { 21 | record := NewRecord("source", LOG_INFO, msg, nil) 22 | sink.AddRecord(record) 23 | sink.Flush() 24 | pWriter.Close() 25 | }("Hello, \nworld") 26 | 27 | bufReader := bufio.NewReader(pReader) 28 | msg, err := bufReader.ReadString('\n') 29 | c.Assert(err, IsNil) 30 | c.Assert(msg, Matches, `{.*"Hello, \\nworld".*}\n`) 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/json_codec.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type JsonCodec struct { 8 | } 9 | 10 | func NewJsonCodec() Codec { 11 | return new(JsonCodec) 12 | } 13 | 14 | func (j *JsonCodec) EncodeRecord(record *Record) ([]byte, error) { 15 | b, err := json.Marshal(record) 16 | if err != nil { 17 | return json.Marshal(map[string]string{"error": err.Error()}) 18 | } 19 | 20 | return b, err 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/json_codec_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "fmt" 5 | . "launchpad.net/gocheck" 6 | ) 7 | 8 | type JsonCodecSuite struct { 9 | JsonCodec 10 | } 11 | 12 | var _ = Suite(&JsonCodecSuite{}) 13 | 14 | func (s *JsonCodecSuite) TestJsonCodec(c *C) { 15 | r := NewRecord("source", LOG_INFO, "Hello world", nil) 16 | m, err := s.EncodeRecord(r) 17 | c.Assert(err, IsNil) 18 | 19 | // The names of these fields are a direct copy of the fields used by the Ruby 20 | // version of steno to prevent breaking the prettifiers. Some of these fields 21 | // can be changed (e.g. `process_id` -> `pid`, `log_level` -> `level), but 22 | // only as long as the prettifiers are also updated. 23 | fields := []string{ 24 | "timestamp", 25 | "process_id", 26 | "source", 27 | "log_level", 28 | "message", 29 | "data", 30 | } 31 | 32 | for _, f := range fields { 33 | c.Check(string(m), Matches, fmt.Sprintf(`{.*"%s":.*}`, f)) 34 | } 35 | } 36 | 37 | func (s *JsonCodecSuite) TestTimestampIsFormattedAsFloat(c *C) { 38 | r := NewRecord("source", LOG_INFO, "Hello world", nil) 39 | m, err := s.EncodeRecord(r) 40 | c.Assert(err, IsNil) 41 | c.Assert(string(m), Matches, `.*"timestamp":\d{10}\.\d{9},.*`) 42 | } 43 | 44 | func (s *JsonCodecSuite) TestEmptyFileLineMethodNotIncluded(c *C) { 45 | r := NewRecord("source", LOG_INFO, "Hello world", nil) 46 | m, err := s.EncodeRecord(r) 47 | c.Assert(err, IsNil) 48 | c.Check(string(m), Not(Matches), `.*"file":.*`) 49 | c.Check(string(m), Not(Matches), `.*"line":.*`) 50 | c.Check(string(m), Not(Matches), `.*"method":.*`) 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/json_prettifier.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | "text/template" 10 | "time" 11 | ) 12 | 13 | const ( 14 | EXCLUDE_NONE = 0 15 | 16 | EXCLUDE_LEVEL = 1 << (iota - 1) 17 | EXCLUDE_TIMESTAMP 18 | EXCLUDE_FILE 19 | EXCLUDE_LINE 20 | EXCLUDE_METHOD 21 | EXCLUDE_DATA 22 | EXCLUDE_MESSAGE 23 | ) 24 | 25 | type JsonPrettifier struct { 26 | entryTemplate *template.Template 27 | } 28 | 29 | func NewJsonPrettifier(flag int) *JsonPrettifier { 30 | fields := []string{ 31 | "{{encodeLevel .Level}}", 32 | "{{encodeTimestamp .Timestamp}}", 33 | "{{encodeFile .File}}", 34 | "{{encodeLine .Line}}", 35 | "{{encodeMethod .Method}}", 36 | "{{encodeData .Data}}", 37 | "{{encodeMessage .Message}}", 38 | } 39 | 40 | for i, _ := range fields { 41 | // the shift count must be an unsigned integer 42 | if (flag & (1 << uint(i))) != 0 { 43 | fields[i] = "" 44 | } 45 | } 46 | 47 | prettifier := new(JsonPrettifier) 48 | format := strings.Join(fields, "") 49 | funcMap := template.FuncMap{ 50 | "encodeTimestamp": encodeTimestamp, 51 | "encodeFile": encodeFile, 52 | "encodeMethod": encodeMethod, 53 | "encodeLine": encodeLine, 54 | "encodeData": encodeData, 55 | "encodeLevel": encodeLevel, 56 | "encodeMessage": encodeMessage, 57 | } 58 | prettifier.entryTemplate = template.Must(template.New("EntryTemplate").Funcs(funcMap).Parse(format)) 59 | 60 | return prettifier 61 | } 62 | 63 | func (p *JsonPrettifier) DecodeJsonLogEntry(logEntry string) (*Record, error) { 64 | record := new(Record) 65 | err := json.Unmarshal([]byte(logEntry), record) 66 | return record, err 67 | } 68 | 69 | func (p *JsonPrettifier) EncodeRecord(record *Record) ([]byte, error) { 70 | buffer := bytes.NewBufferString("") 71 | err := p.entryTemplate.Execute(buffer, record) 72 | return buffer.Bytes(), err 73 | } 74 | 75 | func encodeLevel(level LogLevel) string { 76 | return fmt.Sprintf("%s ", strings.ToUpper(level.String())) 77 | } 78 | 79 | func encodeTimestamp(t RecordTimestamp) string { 80 | ut := time.Unix(int64(t), 0) 81 | return fmt.Sprintf("%s ", ut.Format("2006-01-02 15:04:05")) 82 | } 83 | 84 | func encodeFile(file string) string { 85 | index := strings.LastIndex(file, "/") 86 | return fmt.Sprintf("%s:", file[index+1:]) 87 | } 88 | 89 | func encodeLine(line int) string { 90 | return fmt.Sprintf("%s:", strconv.Itoa(line)) 91 | } 92 | 93 | func encodeMethod(method string) string { 94 | index := strings.LastIndex(method, ".") 95 | return fmt.Sprintf("%s ", method[index+1:]) 96 | } 97 | 98 | func encodeData(data map[string]interface{}) (string, error) { 99 | b, err := json.Marshal(data) 100 | return fmt.Sprintf("%s ", string(b)), err 101 | } 102 | 103 | func encodeMessage(message string) string { 104 | return message 105 | } 106 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/log_level.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type LogLevel struct { 9 | Name string 10 | Priority int 11 | } 12 | 13 | var ( 14 | LOG_OFF = defineLogLevel("off", 0) 15 | LOG_FATAL = defineLogLevel("fatal", 1) 16 | LOG_ERROR = defineLogLevel("error", 5) 17 | LOG_WARN = defineLogLevel("warn", 10) 18 | LOG_INFO = defineLogLevel("info", 15) 19 | LOG_DEBUG = defineLogLevel("debug", 16) 20 | LOG_DEBUG1 = defineLogLevel("debug1", 17) 21 | LOG_DEBUG2 = defineLogLevel("debug2", 18) 22 | LOG_ALL = defineLogLevel("all", 30) 23 | ) 24 | 25 | var levels = make(map[string]LogLevel) 26 | 27 | func defineLogLevel(n string, p int) LogLevel { 28 | x := LogLevel{Name: n, Priority: p} 29 | 30 | levels[n] = x 31 | 32 | return x 33 | } 34 | 35 | func GetLogLevel(name string) (LogLevel, error) { 36 | var x LogLevel 37 | 38 | if x, ok := levels[name]; ok { 39 | return x, nil 40 | } 41 | 42 | err := fmt.Errorf("Undefined log level: %s", name) 43 | return x, err 44 | } 45 | 46 | func (x LogLevel) MarshalJSON() ([]byte, error) { 47 | return json.Marshal(x.Name) 48 | } 49 | 50 | func (x *LogLevel) UnmarshalJSON(data []byte) error { 51 | var n string 52 | 53 | err := json.Unmarshal(data, &n) 54 | if err != nil { 55 | return err 56 | } 57 | 58 | y, err := GetLogLevel(n) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | *x = y 64 | 65 | return nil 66 | } 67 | 68 | func (l LogLevel) String() string { 69 | return l.Name 70 | } 71 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/log_level_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "encoding/json" 5 | . "launchpad.net/gocheck" 6 | ) 7 | 8 | type LogLevelSuite struct { 9 | } 10 | 11 | var _ = Suite(&LogLevelSuite{}) 12 | 13 | func (s *LogLevelSuite) TestNewLogLevel(c *C) { 14 | level := defineLogLevel("foobar", 100) 15 | c.Assert(level, NotNil) 16 | c.Assert(level.Name, Equals, "foobar") 17 | c.Assert(level.Priority, Equals, 100) 18 | } 19 | 20 | func (s *LogLevelSuite) TestGetLevel(c *C) { 21 | l, err := GetLogLevel("info") 22 | c.Assert(l, Equals, LOG_INFO) 23 | c.Assert(err, IsNil) 24 | } 25 | 26 | func (s *LogLevelSuite) TestGetNotExistLevel(c *C) { 27 | l, err := GetLogLevel("foobar") 28 | c.Assert(l, Equals, LogLevel{}) 29 | c.Assert(err, NotNil) 30 | } 31 | 32 | func (s *LogLevelSuite) TestMarshal(c *C) { 33 | m, err := json.Marshal(LOG_INFO) 34 | 35 | c.Assert(err, IsNil) 36 | c.Assert(string(m), Equals, "\"info\"") 37 | } 38 | 39 | func (s *LogLevelSuite) TestUnmarshal(c *C) { 40 | var l LogLevel 41 | 42 | err := json.Unmarshal([]byte("\"info\""), &l) 43 | 44 | c.Assert(err, IsNil) 45 | c.Assert(l, Equals, LOG_INFO) 46 | } 47 | 48 | func (s *LogLevelSuite) TestUnmarshalError(c *C) { 49 | var l LogLevel 50 | 51 | err := json.Unmarshal([]byte("\"undefined\""), &l) 52 | 53 | c.Assert(err.Error(), Matches, "Undefined log level: .*") 54 | c.Assert(l, Equals, LogLevel{}) 55 | } 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/null_sink_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | type nullSink struct { 4 | records []*Record 5 | } 6 | 7 | func newNullSink() *nullSink { 8 | nSink := new(nullSink) 9 | nSink.records = make([]*Record, 0, 10) 10 | return nSink 11 | } 12 | 13 | func (nSink *nullSink) AddRecord(record *Record) { 14 | nSink.records = append(nSink.records, record) 15 | } 16 | 17 | func (nSink *nullSink) Flush() { 18 | 19 | } 20 | 21 | func (nSink *nullSink) SetCodec(codec Codec) { 22 | 23 | } 24 | 25 | func (nSink *nullSink) GetCodec() Codec { 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/perf_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func BenchmarkNoSink(b *testing.B) { 8 | Init(&Config{}) 9 | 10 | loggers = make(map[string]*BaseLogger) 11 | logger := NewLogger("nosink") 12 | 13 | performBenchmark(logger, b) 14 | } 15 | 16 | func BenchmarkDevNullSink(b *testing.B) { 17 | Init(&Config{ 18 | Sinks: []Sink{NewFileSink("/dev/null")}, 19 | }) 20 | 21 | loggers = make(map[string]*BaseLogger) 22 | logger := NewLogger("dev_null_sink") 23 | 24 | performBenchmark(logger, b) 25 | } 26 | 27 | func BenchmarkDevNullSinkWithLOC(b *testing.B) { 28 | Init(&Config{ 29 | Sinks: []Sink{NewFileSink("/dev/null")}, 30 | EnableLOC: true, 31 | }) 32 | 33 | loggers = make(map[string]*BaseLogger) 34 | logger := NewLogger("dev_null_sink_with_loc") 35 | 36 | performBenchmark(logger, b) 37 | } 38 | 39 | func BenchmarkDevNullSinkWithData(b *testing.B) { 40 | Init(&Config{ 41 | Sinks: []Sink{NewFileSink("/dev/null")}, 42 | }) 43 | 44 | loggers = make(map[string]*BaseLogger) 45 | logger := NewLogger("dev_null_sink_with_data") 46 | logger.Set("key1", "value1") 47 | logger.Set("key2", "value2") 48 | 49 | performBenchmark(logger, b) 50 | } 51 | 52 | func performBenchmark(logger *Logger, b *testing.B) { 53 | b.ResetTimer() 54 | for i := 0; i < b.N; i++ { 55 | logger.Info("Hello, world.") 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/record.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "runtime" 7 | "strings" 8 | "time" 9 | ) 10 | 11 | type RecordTimestamp float64 12 | 13 | func (t RecordTimestamp) MarshalJSON() ([]byte, error) { 14 | return []byte(fmt.Sprintf("%.9f", t)), nil 15 | } 16 | 17 | type Record struct { 18 | Timestamp RecordTimestamp `json:"timestamp"` 19 | Pid int `json:"process_id"` 20 | Source string `json:"source"` 21 | Level LogLevel `json:"log_level"` 22 | Message string `json:"message"` 23 | Data map[string]interface{} `json:"data"` 24 | File string `json:"file,omitempty"` 25 | Line int `json:"line,omitempty"` 26 | Method string `json:"method,omitempty"` 27 | } 28 | 29 | var pid int 30 | 31 | func init() { 32 | pid = os.Getpid() 33 | } 34 | 35 | func NewRecord(s string, l LogLevel, m string, d map[string]interface{}) *Record { 36 | r := &Record{ 37 | Timestamp: RecordTimestamp(time.Now().UnixNano()) / 1000000000, 38 | Pid: pid, 39 | Source: s, 40 | Level: l, 41 | Message: m, 42 | Data: d, 43 | } 44 | 45 | if getConfig().EnableLOC { 46 | var function *runtime.Func 47 | var file string 48 | var line int 49 | 50 | pc := make([]uintptr, 50) 51 | nptrs := runtime.Callers(2, pc) 52 | for i := 0; i < nptrs; i++ { 53 | function = runtime.FuncForPC(pc[i]) 54 | file, line = function.FileLine(pc[i]) 55 | if !strings.HasSuffix(file, "logger.go") { 56 | break 57 | } 58 | } 59 | r.File = file 60 | r.Line = line 61 | r.Method = function.Name() 62 | } 63 | 64 | return r 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/record_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | . "launchpad.net/gocheck" 5 | ) 6 | 7 | type RecordSuite struct{} 8 | 9 | var _ = Suite(&RecordSuite{}) 10 | 11 | func (s *RecordSuite) TestNewRecordWithLOC(c *C) { 12 | config.EnableLOC = true 13 | r := NewRecord("source", LOG_INFO, "hello", nil) 14 | config.EnableLOC = false 15 | 16 | c.Check(r.File, Matches, ".*record_test.go$") 17 | c.Check(r.Line, Equals, 13) 18 | c.Check(r.Method, Matches, `.*\.\(\*RecordSuite\)\.TestNewRecordWithLOC`) 19 | } 20 | 21 | func (s *RecordSuite) TestNewRecordWithoutLOC(c *C) { 22 | r := NewRecord("source", LOG_INFO, "hello", nil) 23 | 24 | c.Check(r.File, Equals, "") 25 | c.Check(r.Line, Equals, 0) 26 | c.Check(r.Method, Equals, "") 27 | } 28 | 29 | func (s *RecordSuite) TestRecordPid(c *C) { 30 | r := NewRecord("source", LOG_INFO, "hello", nil) 31 | 32 | c.Check(r.Pid, Not(Equals), 0) 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/regexp.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "regexp" 5 | ) 6 | 7 | // loggerRegexp* used to match log name and log level 8 | var loggerRegexp *regexp.Regexp 9 | var loggerRegexpLevel *LogLevel 10 | 11 | func SetLoggerRegexp(pattern string, level LogLevel) error { 12 | loggersMutex.Lock() 13 | defer loggersMutex.Unlock() 14 | 15 | clearLoggerRegexp() 16 | return setLoggerRegexp(pattern, level) 17 | } 18 | 19 | func ClearLoggerRegexp() { 20 | loggersMutex.Lock() 21 | defer loggersMutex.Unlock() 22 | 23 | clearLoggerRegexp() 24 | } 25 | 26 | func setLoggerRegexp(pattern string, level LogLevel) error { 27 | regExp, err := regexp.Compile(pattern) 28 | if err != nil { 29 | return err 30 | } 31 | 32 | loggerRegexp = regExp 33 | loggerRegexpLevel = &level 34 | 35 | for name, logger := range loggers { 36 | if loggerRegexp.MatchString(name) { 37 | logger.level = level 38 | } 39 | } 40 | 41 | return nil 42 | } 43 | 44 | func clearLoggerRegexp() { 45 | if loggerRegexp == nil { 46 | return 47 | } 48 | 49 | for name, logger := range loggers { 50 | if loggerRegexp.MatchString(name) { 51 | logger.level = getConfig().Level 52 | } 53 | } 54 | 55 | loggerRegexp = nil 56 | loggerRegexpLevel = nil 57 | } 58 | 59 | func computeLevel(name string) LogLevel { 60 | if loggerRegexpLevel != nil && loggerRegexp.MatchString(name) { 61 | return *loggerRegexpLevel 62 | } 63 | 64 | return getConfig().Level 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/sink.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | type Sink interface { 4 | AddRecord(record *Record) 5 | Flush() 6 | 7 | SetCodec(codec Codec) 8 | GetCodec() Codec 9 | } 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/steno.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "encoding/json" 5 | "sync" 6 | ) 7 | 8 | // Global configs 9 | var config Config 10 | 11 | // loggersMutex protects accesses to loggers and regexp 12 | var loggersMutex = &sync.Mutex{} 13 | 14 | // loggersMutex protects accesses to loggers and regexp 15 | var configMutex = &sync.RWMutex{} 16 | 17 | // loggers only saves BaseLogger 18 | var loggers = make(map[string]*BaseLogger) 19 | 20 | func Init(c *Config) { 21 | loggersMutex.Lock() 22 | defer loggersMutex.Unlock() 23 | 24 | if c.Level == (LogLevel{}) { 25 | c.Level = LOG_INFO 26 | } 27 | 28 | if c.Codec == nil { 29 | c.Codec = NewJsonCodec() 30 | } 31 | 32 | if c.Sinks == nil { 33 | c.Sinks = []Sink{} 34 | } 35 | 36 | for _, sink := range c.Sinks { 37 | if sink.GetCodec() == nil { 38 | sink.SetCodec(c.Codec) 39 | } 40 | } 41 | 42 | setConfig(*c) 43 | 44 | for name, _ := range loggers { 45 | loggers[name] = nil 46 | } 47 | } 48 | 49 | func NewLogger(name string) *Logger { 50 | loggersMutex.Lock() 51 | defer loggersMutex.Unlock() 52 | 53 | l := loggers[name] 54 | if l == nil { 55 | bl := &BaseLogger{ 56 | name: name, 57 | sinks: getConfig().Sinks, 58 | level: computeLevel(name), 59 | } 60 | 61 | loggers[name] = bl 62 | l = bl 63 | } 64 | 65 | return &Logger{L: l} 66 | } 67 | 68 | func getConfig() Config { 69 | configMutex.RLock() 70 | defer configMutex.RUnlock() 71 | 72 | return config 73 | } 74 | 75 | func setConfig(newConfig Config) { 76 | configMutex.Lock() 77 | defer configMutex.Unlock() 78 | 79 | config = newConfig 80 | } 81 | 82 | func loggersInJson() string { 83 | bytes, _ := json.Marshal(loggers) 84 | return string(bytes) 85 | } 86 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/steno_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | . "launchpad.net/gocheck" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | func Test(t *testing.T) { 10 | TestingT(t) 11 | } 12 | 13 | type StenoSuite struct { 14 | } 15 | 16 | var _ = Suite(&StenoSuite{}) 17 | 18 | func (s *StenoSuite) SetUpTest(c *C) { 19 | cfg := Config{} 20 | cfg.Sinks = []Sink{NewIOSink(os.Stdout)} 21 | 22 | loggers = make(map[string]*BaseLogger) 23 | 24 | Init(&cfg) 25 | } 26 | 27 | func (s *StenoSuite) TearDownTest(c *C) { 28 | Init(&Config{}) 29 | 30 | loggers = nil 31 | loggerRegexp = nil 32 | loggerRegexpLevel = nil 33 | } 34 | 35 | func (s *StenoSuite) TestInitLoggers(c *C) { 36 | c.Assert(loggers, HasLen, 0) 37 | } 38 | 39 | func (s *StenoSuite) TestDefaultConfig(c *C) { 40 | c.Assert(config.Level, Equals, LOG_INFO) 41 | } 42 | 43 | func (s *StenoSuite) TestLoggersInJson(c *C) { 44 | c.Assert(loggersInJson(), Matches, "{.*}") 45 | } 46 | 47 | func (s *StenoSuite) TestSetLoggerRegexp(c *C) { 48 | // level is a field of BaseLogger, hence type cast is needed 49 | logger1 := NewLogger("test").L.(*BaseLogger) 50 | logger2 := NewLogger("test2").L.(*BaseLogger) 51 | logger3 := NewLogger("test3").L.(*BaseLogger) 52 | 53 | c.Assert(logger1.level, Equals, LOG_INFO) 54 | c.Assert(logger2.level, Equals, LOG_INFO) 55 | c.Assert(logger3.level, Equals, LOG_INFO) 56 | 57 | SetLoggerRegexp("te", LOG_FATAL) 58 | c.Assert(logger1.level, Equals, LOG_FATAL) 59 | c.Assert(logger2.level, Equals, LOG_FATAL) 60 | c.Assert(logger3.level, Equals, LOG_FATAL) 61 | 62 | SetLoggerRegexp("test", LOG_ERROR) 63 | c.Assert(logger1.level, Equals, LOG_ERROR) 64 | c.Assert(logger2.level, Equals, LOG_ERROR) 65 | c.Assert(logger3.level, Equals, LOG_ERROR) 66 | 67 | SetLoggerRegexp("test$", LOG_WARN) 68 | c.Assert(logger1.level, Equals, LOG_WARN) 69 | c.Assert(logger2.level, Equals, LOG_INFO) 70 | c.Assert(logger3.level, Equals, LOG_INFO) 71 | } 72 | 73 | func (s *StenoSuite) TestClearLoggerRegexp(c *C) { 74 | // level is a field of BaseLogger, hence type cast is needed 75 | logger1 := NewLogger("test").L.(*BaseLogger) 76 | logger2 := NewLogger("test2").L.(*BaseLogger) 77 | logger3 := NewLogger("test3").L.(*BaseLogger) 78 | 79 | c.Assert(logger1.level, Equals, LOG_INFO) 80 | c.Assert(logger2.level, Equals, LOG_INFO) 81 | c.Assert(logger3.level, Equals, LOG_INFO) 82 | 83 | SetLoggerRegexp("test", LOG_FATAL) 84 | c.Assert(logger1.level, Equals, LOG_FATAL) 85 | c.Assert(logger2.level, Equals, LOG_FATAL) 86 | c.Assert(logger3.level, Equals, LOG_FATAL) 87 | 88 | ClearLoggerRegexp() 89 | c.Assert(logger1.level, Equals, LOG_INFO) 90 | c.Assert(logger2.level, Equals, LOG_INFO) 91 | c.Assert(logger3.level, Equals, LOG_INFO) 92 | } 93 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/syslog/syslog_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !windows,!plan9 6 | 7 | package syslog 8 | 9 | import ( 10 | "errors" 11 | "net" 12 | ) 13 | 14 | // unixSyslog opens a connection to the syslog daemon running on the 15 | // local machine using a Unix domain socket. 16 | 17 | func unixSyslog() (conn serverConn, err error) { 18 | logTypes := []string{"unixgram", "unix"} 19 | logPaths := []string{"/dev/log", "/var/run/syslog"} 20 | var raddr string 21 | for _, network := range logTypes { 22 | for _, path := range logPaths { 23 | raddr = path 24 | conn, err := net.Dial(network, raddr) 25 | if err != nil { 26 | continue 27 | } else { 28 | return netConn{conn}, nil 29 | } 30 | } 31 | } 32 | return nil, errors.New("Could not connect to local syslog socket") 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/syslog/syslog_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package syslog provides a simple interface to the system log service. 6 | package syslog 7 | 8 | // BUG(brainman): This package is not implemented on Windows yet. 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/syslog_sink.go: -------------------------------------------------------------------------------- 1 | // +build !windows,!plan9 2 | 3 | package gosteno 4 | 5 | import ( 6 | syslog "github.com/cloudfoundry/gosteno/syslog" 7 | "sync" 8 | "errors" 9 | ) 10 | 11 | const ( 12 | MaxMessageSize = 1024 * 3 13 | TruncatePostfix = "..." 14 | ) 15 | 16 | type Syslog struct { 17 | writer *syslog.Writer 18 | codec Codec 19 | 20 | sync.Mutex 21 | } 22 | 23 | func NewSyslogSink(namespace string) *Syslog { 24 | writer, err := syslog.New(syslog.LOG_DEBUG, namespace) 25 | if err != nil { 26 | panic(errors.New("Could not setup logging to syslog: " + err.Error())) 27 | } 28 | 29 | syslog := new(Syslog) 30 | syslog.writer = writer 31 | return syslog 32 | } 33 | 34 | func (s *Syslog) AddRecord(record *Record) { 35 | truncate(record) 36 | 37 | bytes, _ := s.codec.EncodeRecord(record) 38 | msg := string(bytes) 39 | 40 | s.Lock() 41 | defer s.Unlock() 42 | 43 | switch record.Level { 44 | case LOG_FATAL: 45 | s.writer.Crit(msg) 46 | case LOG_ERROR: 47 | s.writer.Err(msg) 48 | case LOG_WARN: 49 | s.writer.Warning(msg) 50 | case LOG_INFO: 51 | s.writer.Info(msg) 52 | case LOG_DEBUG, LOG_DEBUG1, LOG_DEBUG2: 53 | s.writer.Debug(msg) 54 | default: 55 | panic("Unknown log level: " + record.Level.Name) 56 | } 57 | } 58 | 59 | func (s *Syslog) Flush() { 60 | // No impl. 61 | } 62 | 63 | func (s *Syslog) SetCodec(codec Codec) { 64 | s.Lock() 65 | defer s.Unlock() 66 | 67 | s.codec = codec 68 | } 69 | 70 | func (s *Syslog) GetCodec() Codec { 71 | s.Lock() 72 | defer s.Unlock() 73 | 74 | return s.codec 75 | } 76 | 77 | func truncate(record *Record) { 78 | if len(record.Message) <= MaxMessageSize { 79 | return 80 | } 81 | 82 | record.Message = record.Message[:MaxMessageSize-len(TruncatePostfix)] + TruncatePostfix 83 | } 84 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/syslog_sink_test.go: -------------------------------------------------------------------------------- 1 | // +build !windows,!plan9 2 | 3 | package gosteno 4 | 5 | import ( 6 | "fmt" 7 | . "launchpad.net/gocheck" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | type SyslogSinkSuite struct { 13 | } 14 | 15 | var _ = Suite(&SyslogSinkSuite{}) 16 | 17 | func (s *SyslogSinkSuite) TestTruncate(c *C) { 18 | msg := generateString(MaxMessageSize - 1) 19 | record := &Record{ 20 | Message: msg, 21 | } 22 | truncate(record) 23 | c.Check(record.Message, Equals, msg) 24 | 25 | msg2 := generateString(MaxMessageSize + 1) 26 | record2 := &Record{ 27 | Message: msg2, 28 | } 29 | truncate(record2) 30 | c.Check(len(record2.Message), Equals, MaxMessageSize) 31 | c.Check(record2.Message[:MaxMessageSize-3], Equals, msg2[:MaxMessageSize-3]) 32 | c.Check(strings.HasSuffix(record2.Message, "..."), Equals, true) 33 | } 34 | 35 | func generateString(length int) (ret string) { 36 | file, _ := os.Open("/dev/urandom") 37 | b := make([]byte, length/2) 38 | file.Read(b) 39 | file.Close() 40 | 41 | if length%2 == 0 { 42 | ret = fmt.Sprintf("%x", b) 43 | } else { 44 | ret = fmt.Sprintf("0%x", b) 45 | } 46 | 47 | return 48 | } 49 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/testing_sink.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type TestingSink struct { 8 | records []*Record 9 | 10 | sync.RWMutex 11 | } 12 | 13 | var theGlobalTestSink *TestingSink 14 | var globalSyncMutex = &sync.RWMutex{} 15 | 16 | func EnterTestMode(logLevel ...LogLevel) { 17 | globalSyncMutex.Lock() 18 | defer globalSyncMutex.Unlock() 19 | 20 | theGlobalTestSink = NewTestingSink() 21 | 22 | stenoConfig := Config{ 23 | Sinks: []Sink{theGlobalTestSink}, 24 | } 25 | 26 | if len(logLevel) > 0 { 27 | stenoConfig.Level = logLevel[0] 28 | } 29 | 30 | Init(&stenoConfig) 31 | } 32 | 33 | func GetMeTheGlobalTestSink() *TestingSink { 34 | globalSyncMutex.RLock() 35 | defer globalSyncMutex.RUnlock() 36 | 37 | return theGlobalTestSink 38 | } 39 | 40 | func NewTestingSink() *TestingSink { 41 | return &TestingSink{ 42 | records: make([]*Record, 0, 10), 43 | } 44 | } 45 | 46 | func (tSink *TestingSink) AddRecord(record *Record) { 47 | tSink.Lock() 48 | defer tSink.Unlock() 49 | 50 | tSink.records = append(tSink.records, record) 51 | } 52 | 53 | func (tSink *TestingSink) Flush() { 54 | 55 | } 56 | 57 | func (tSink *TestingSink) SetCodec(codec Codec) { 58 | 59 | } 60 | 61 | func (tSink *TestingSink) GetCodec() Codec { 62 | return nil 63 | } 64 | 65 | func (tSink *TestingSink) Records() []*Record { 66 | tSink.RLock() 67 | defer tSink.RUnlock() 68 | 69 | return tSink.records 70 | } 71 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/cloudfoundry/gosteno/testing_sink_test.go: -------------------------------------------------------------------------------- 1 | package gosteno 2 | 3 | import ( 4 | . "launchpad.net/gocheck" 5 | ) 6 | 7 | type TestingSinkSuite struct { 8 | } 9 | 10 | var _ = Suite(&TestingSinkSuite{}) 11 | 12 | func (s *TestingSinkSuite) TestAddRecord(c *C) { 13 | sink := NewTestingSink() 14 | 15 | data := map[string]interface{}{"a": "b"} 16 | record := NewRecord("source", LOG_INFO, "Hello, world!", data) 17 | sink.AddRecord(record) 18 | 19 | c.Assert(sink.Records(), HasLen, 1) 20 | c.Check(sink.Records()[0].Message, Equals, "Hello, world!") 21 | c.Check(sink.Records()[0].Data, DeepEquals, data) 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/garyburd/redigo/internal/commandinfo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package internal 16 | 17 | import ( 18 | "strings" 19 | ) 20 | 21 | const ( 22 | WatchState = 1 << iota 23 | MultiState 24 | SubscribeState 25 | MonitorState 26 | ) 27 | 28 | type CommandInfo struct { 29 | Set, Clear int 30 | } 31 | 32 | var commandInfos = map[string]CommandInfo{ 33 | "WATCH": {Set: WatchState}, 34 | "UNWATCH": {Clear: WatchState}, 35 | "MULTI": {Set: MultiState}, 36 | "EXEC": {Clear: WatchState | MultiState}, 37 | "DISCARD": {Clear: WatchState | MultiState}, 38 | "PSUBSCRIBE": {Set: SubscribeState}, 39 | "SUBSCRIBE": {Set: SubscribeState}, 40 | "MONITOR": {Set: MonitorState}, 41 | } 42 | 43 | func LookupCommandInfo(commandName string) CommandInfo { 44 | return commandInfos[strings.ToUpper(commandName)] 45 | } 46 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/garyburd/redigo/internal/redistest/testdb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | // Package redistest contains utilities for writing Redigo tests. 16 | package redistest 17 | 18 | import ( 19 | "errors" 20 | "time" 21 | 22 | "github.com/garyburd/redigo/redis" 23 | ) 24 | 25 | type testConn struct { 26 | redis.Conn 27 | } 28 | 29 | func (t testConn) Close() error { 30 | _, err := t.Conn.Do("SELECT", "9") 31 | if err != nil { 32 | return nil 33 | } 34 | _, err = t.Conn.Do("FLUSHDB") 35 | if err != nil { 36 | return err 37 | } 38 | return t.Conn.Close() 39 | } 40 | 41 | // Dial dials the local Redis server and selects database 9. To prevent 42 | // stomping on real data, DialTestDB fails if database 9 contains data. The 43 | // returned connection flushes database 9 on close. 44 | func Dial() (redis.Conn, error) { 45 | c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | _, err = c.Do("SELECT", "9") 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | n, err := redis.Int(c.Do("DBSIZE")) 56 | if err != nil { 57 | return nil, err 58 | } 59 | 60 | if n != 0 { 61 | return nil, errors.New("database #9 is not empty, test can not continue") 62 | } 63 | 64 | return testConn{c}, nil 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/garyburd/redigo/redis/redis.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | // Error represents an error returned in a command reply. 18 | type Error string 19 | 20 | func (err Error) Error() string { return string(err) } 21 | 22 | // Conn represents a connection to a Redis server. 23 | type Conn interface { 24 | // Close closes the connection. 25 | Close() error 26 | 27 | // Err returns a non-nil value if the connection is broken. The returned 28 | // value is either the first non-nil value returned from the underlying 29 | // network connection or a protocol parsing error. Applications should 30 | // close broken connections. 31 | Err() error 32 | 33 | // Do sends a command to the server and returns the received reply. 34 | Do(commandName string, args ...interface{}) (reply interface{}, err error) 35 | 36 | // Send writes the command to the client's output buffer. 37 | Send(commandName string, args ...interface{}) error 38 | 39 | // Flush flushes the output buffer to the Redis server. 40 | Flush() error 41 | 42 | // Receive receives a single reply from the Redis server 43 | Receive() (reply interface{}, err error) 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/garyburd/redigo/redis/test_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "bufio" 19 | "net" 20 | "time" 21 | ) 22 | 23 | func SetNowFunc(f func() time.Time) { 24 | nowFunc = f 25 | } 26 | 27 | type nopCloser struct{ net.Conn } 28 | 29 | func (nopCloser) Close() error { return nil } 30 | 31 | // NewConnBufio is a hook for tests. 32 | func NewConnBufio(rw bufio.ReadWriter) Conn { 33 | return &conn{br: rw.Reader, bw: rw.Writer, conn: nopCloser{}} 34 | } 35 | 36 | var ( 37 | ErrNegativeInt = errNegativeInt 38 | ) 39 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/nu7hatch/gouuid/.gitignore: -------------------------------------------------------------------------------- 1 | _obj 2 | _test 3 | *.6 4 | *.out 5 | _testmain.go 6 | \#* 7 | .\#* 8 | *.log 9 | _cgo* 10 | *.o 11 | *.a 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/nu7hatch/gouuid/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 by Krzysztof Kowalik 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/nu7hatch/gouuid/README.md: -------------------------------------------------------------------------------- 1 | # Pure Go UUID implementation 2 | 3 | This package provides immutable UUID structs and the functions 4 | NewV3, NewV4, NewV5 and Parse() for generating versions 3, 4 5 | and 5 UUIDs as specified in [RFC 4122](http://www.ietf.org/rfc/rfc4122.txt). 6 | 7 | ## Installation 8 | 9 | Use the `go` tool: 10 | 11 | $ go get github.com/nu7hatch/gouuid 12 | 13 | ## Usage 14 | 15 | See [documentation and examples](http://godoc.org/github.com/nu7hatch/gouuid) 16 | for more information. 17 | 18 | ## Copyright 19 | 20 | Copyright (C) 2011 by Krzysztof Kowalik . See [COPYING](https://github.com/nu7hatch/gouuid/tree/master/COPYING) 21 | file for details. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/nu7hatch/gouuid/example_test.go: -------------------------------------------------------------------------------- 1 | package uuid_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/nu7hatch/gouuid" 6 | ) 7 | 8 | func ExampleNewV4() { 9 | u4, err := uuid.NewV4() 10 | if err != nil { 11 | fmt.Println("error:", err) 12 | return 13 | } 14 | fmt.Println(u4) 15 | } 16 | 17 | func ExampleNewV5() { 18 | u5, err := uuid.NewV5(uuid.NamespaceURL, []byte("nu7hat.ch")) 19 | if err != nil { 20 | fmt.Println("error:", err) 21 | return 22 | } 23 | fmt.Println(u5) 24 | } 25 | 26 | func ExampleParseHex() { 27 | u, err := uuid.ParseHex("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 28 | if err != nil { 29 | fmt.Println("error:", err) 30 | return 31 | } 32 | fmt.Println(u) 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/.gitignore: -------------------------------------------------------------------------------- 1 | *.[68] 2 | *.a 3 | *.out 4 | *.swp 5 | _obj 6 | _testmain.go 7 | cmd/metrics-bench/metrics-bench 8 | cmd/metrics-example/metrics-example 9 | cmd/never-read/never-read 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Richard Crowley. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | disclaimer in the documentation and/or other materials provided 13 | with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY RICHARD CROWLEY ``AS IS'' AND ANY EXPRESS 16 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL RICHARD CROWLEY OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 25 | THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | The views and conclusions contained in the software and documentation 28 | are those of the authors and should not be interpreted as representing 29 | official policies, either expressed or implied, of Richard Crowley. 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/README.md: -------------------------------------------------------------------------------- 1 | go-metrics 2 | ========== 3 | 4 | Go port of Coda Hale's Metrics library: . 5 | 6 | Documentation: . 7 | 8 | Usage 9 | ----- 10 | 11 | Create and update metrics: 12 | 13 | ```go 14 | c := metrics.NewCounter() 15 | metrics.Register("foo", c) 16 | c.Inc(47) 17 | 18 | g := metrics.NewGauge() 19 | metrics.Register("bar", g) 20 | g.Update(47) 21 | 22 | s := metrics.NewExpDecaySample(1028, 0.015) // or metrics.NewUniformSample(1028) 23 | h := metrics.NewHistogram(s) 24 | metrics.Register("baz", h) 25 | h.Update(47) 26 | 27 | m := metrics.NewMeter() 28 | metrics.Register("quux", m) 29 | m.Mark(47) 30 | 31 | t := metrics.NewTimer() 32 | metrics.Register("bang", t) 33 | t.Time(func() {}) 34 | t.Update(47) 35 | ``` 36 | 37 | Periodically log every metric in human-readable form to standard error: 38 | 39 | ```go 40 | go metrics.Log(metrics.DefaultRegistry, 60e9, log.New(os.Stderr, "metrics: ", log.Lmicroseconds)) 41 | ``` 42 | 43 | Periodically log every metric in slightly-more-parseable form to syslog: 44 | 45 | ```go 46 | w, _ := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics") 47 | go metrics.Syslog(metrics.DefaultRegistry, 60e9, w) 48 | ``` 49 | 50 | Periodically emit every metric to Graphite: 51 | 52 | ```go 53 | addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003") 54 | go metrics.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr) 55 | ``` 56 | 57 | Periodically emit every metric into InfluxDB: 58 | 59 | ```go 60 | import "github.com/rcrowley/go-metrics/influxdb" 61 | 62 | go influxdb.Influxdb(metrics.DefaultRegistry, 10e9, &influxdb.Config{ 63 | Host: "127.0.0.1:8086", 64 | Database: "metrics", 65 | Username: "test", 66 | Password: "test", 67 | }) 68 | ``` 69 | 70 | Periodically upload every metric to Librato: 71 | 72 | ```go 73 | import "github.com/rcrowley/go-metrics/librato" 74 | 75 | go librato.Librato(metrics.DefaultRegistry, 76 | 10e9, // interval 77 | "example@example.com", // account owner email address 78 | "token", // Librato API token 79 | "hostname", // source 80 | []float64{0.95}, // precentiles to send 81 | time.Millisecond, // time unit 82 | ) 83 | ``` 84 | 85 | Periodically emit every metric to StatHat: 86 | 87 | ```go 88 | import "github.com/rcrowley/go-metrics/stathat" 89 | 90 | go stathat.Stathat(metrics.DefaultRegistry, 10e9, "example@example.com") 91 | ``` 92 | 93 | Installation 94 | ------------ 95 | 96 | ```sh 97 | go get github.com/rcrowley/go-metrics 98 | ``` 99 | 100 | StatHat support additionally requires their Go client: 101 | 102 | ```sh 103 | go get github.com/stathat/go 104 | ``` 105 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-bench/metrics-bench.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/rcrowley/go-metrics" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | r := metrics.NewRegistry() 11 | for i := 0; i < 10000; i++ { 12 | r.Register(fmt.Sprintf("counter-%d", i), metrics.NewCounter()) 13 | r.Register(fmt.Sprintf("gauge-%d", i), metrics.NewGauge()) 14 | r.Register(fmt.Sprintf("gaugefloat64-%d", i), metrics.NewGaugeFloat64()) 15 | r.Register(fmt.Sprintf("histogram-uniform-%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028))) 16 | r.Register(fmt.Sprintf("histogram-exp-%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015))) 17 | r.Register(fmt.Sprintf("meter-%d", i), metrics.NewMeter()) 18 | } 19 | time.Sleep(600e9) 20 | } 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/never-read/never-read.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003") 10 | l, err := net.ListenTCP("tcp", addr) 11 | if nil != err { 12 | log.Fatalln(err) 13 | } 14 | log.Println("listening", l.Addr()) 15 | for { 16 | c, err := l.AcceptTCP() 17 | if nil != err { 18 | log.Fatalln(err) 19 | } 20 | log.Println("accepted", c.RemoteAddr()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/counter_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "testing" 4 | 5 | func BenchmarkCounter(b *testing.B) { 6 | c := NewCounter() 7 | b.ResetTimer() 8 | for i := 0; i < b.N; i++ { 9 | c.Inc(1) 10 | } 11 | } 12 | 13 | func TestCounterClear(t *testing.T) { 14 | c := NewCounter() 15 | c.Inc(1) 16 | c.Clear() 17 | if count := c.Count(); 0 != count { 18 | t.Errorf("c.Count(): 0 != %v\n", count) 19 | } 20 | } 21 | 22 | func TestCounterDec1(t *testing.T) { 23 | c := NewCounter() 24 | c.Dec(1) 25 | if count := c.Count(); -1 != count { 26 | t.Errorf("c.Count(): -1 != %v\n", count) 27 | } 28 | } 29 | 30 | func TestCounterDec2(t *testing.T) { 31 | c := NewCounter() 32 | c.Dec(2) 33 | if count := c.Count(); -2 != count { 34 | t.Errorf("c.Count(): -2 != %v\n", count) 35 | } 36 | } 37 | 38 | func TestCounterInc1(t *testing.T) { 39 | c := NewCounter() 40 | c.Inc(1) 41 | if count := c.Count(); 1 != count { 42 | t.Errorf("c.Count(): 1 != %v\n", count) 43 | } 44 | } 45 | 46 | func TestCounterInc2(t *testing.T) { 47 | c := NewCounter() 48 | c.Inc(2) 49 | if count := c.Count(); 2 != count { 50 | t.Errorf("c.Count(): 2 != %v\n", count) 51 | } 52 | } 53 | 54 | func TestCounterSnapshot(t *testing.T) { 55 | c := NewCounter() 56 | c.Inc(1) 57 | snapshot := c.Snapshot() 58 | c.Inc(1) 59 | if count := snapshot.Count(); 1 != count { 60 | t.Errorf("c.Count(): 1 != %v\n", count) 61 | } 62 | } 63 | 64 | func TestCounterZero(t *testing.T) { 65 | c := NewCounter() 66 | if count := c.Count(); 0 != count { 67 | t.Errorf("c.Count(): 0 != %v\n", count) 68 | } 69 | } 70 | 71 | func TestGetOrRegisterCounter(t *testing.T) { 72 | r := NewRegistry() 73 | NewRegisteredCounter("foo", r).Inc(47) 74 | if c := GetOrRegisterCounter("foo", r); 47 != c.Count() { 75 | t.Fatal(c) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/debug_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "runtime" 5 | "runtime/debug" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func BenchmarkDebugGCStats(b *testing.B) { 11 | r := NewRegistry() 12 | RegisterDebugGCStats(r) 13 | b.ResetTimer() 14 | for i := 0; i < b.N; i++ { 15 | CaptureDebugGCStatsOnce(r) 16 | } 17 | } 18 | 19 | func TestDebugGCStatsBlocking(t *testing.T) { 20 | if g := runtime.GOMAXPROCS(0); g < 2 { 21 | t.Skipf("skipping TestDebugGCMemStatsBlocking with GOMAXPROCS=%d\n", g) 22 | return 23 | } 24 | ch := make(chan int) 25 | go testDebugGCStatsBlocking(ch) 26 | var gcStats debug.GCStats 27 | t0 := time.Now() 28 | debug.ReadGCStats(&gcStats) 29 | t1 := time.Now() 30 | t.Log("i++ during debug.ReadGCStats:", <-ch) 31 | go testDebugGCStatsBlocking(ch) 32 | d := t1.Sub(t0) 33 | t.Log(d) 34 | time.Sleep(d) 35 | t.Log("i++ during time.Sleep:", <-ch) 36 | } 37 | 38 | func testDebugGCStatsBlocking(ch chan int) { 39 | i := 0 40 | for { 41 | select { 42 | case ch <- i: 43 | return 44 | default: 45 | i++ 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/gauge.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "sync/atomic" 4 | 5 | // Gauges hold an int64 value that can be set arbitrarily. 6 | type Gauge interface { 7 | Snapshot() Gauge 8 | Update(int64) 9 | Value() int64 10 | } 11 | 12 | // GetOrRegisterGauge returns an existing Gauge or constructs and registers a 13 | // new StandardGauge. 14 | func GetOrRegisterGauge(name string, r Registry) Gauge { 15 | if nil == r { 16 | r = DefaultRegistry 17 | } 18 | return r.GetOrRegister(name, NewGauge).(Gauge) 19 | } 20 | 21 | // NewGauge constructs a new StandardGauge. 22 | func NewGauge() Gauge { 23 | if UseNilMetrics { 24 | return NilGauge{} 25 | } 26 | return &StandardGauge{0} 27 | } 28 | 29 | // NewRegisteredGauge constructs and registers a new StandardGauge. 30 | func NewRegisteredGauge(name string, r Registry) Gauge { 31 | c := NewGauge() 32 | if nil == r { 33 | r = DefaultRegistry 34 | } 35 | r.Register(name, c) 36 | return c 37 | } 38 | 39 | // GaugeSnapshot is a read-only copy of another Gauge. 40 | type GaugeSnapshot int64 41 | 42 | // Snapshot returns the snapshot. 43 | func (g GaugeSnapshot) Snapshot() Gauge { return g } 44 | 45 | // Update panics. 46 | func (GaugeSnapshot) Update(int64) { 47 | panic("Update called on a GaugeSnapshot") 48 | } 49 | 50 | // Value returns the value at the time the snapshot was taken. 51 | func (g GaugeSnapshot) Value() int64 { return int64(g) } 52 | 53 | // NilGauge is a no-op Gauge. 54 | type NilGauge struct{} 55 | 56 | // Snapshot is a no-op. 57 | func (NilGauge) Snapshot() Gauge { return NilGauge{} } 58 | 59 | // Update is a no-op. 60 | func (NilGauge) Update(v int64) {} 61 | 62 | // Value is a no-op. 63 | func (NilGauge) Value() int64 { return 0 } 64 | 65 | // StandardGauge is the standard implementation of a Gauge and uses the 66 | // sync/atomic package to manage a single int64 value. 67 | type StandardGauge struct { 68 | value int64 69 | } 70 | 71 | // Snapshot returns a read-only copy of the gauge. 72 | func (g *StandardGauge) Snapshot() Gauge { 73 | return GaugeSnapshot(g.Value()) 74 | } 75 | 76 | // Update updates the gauge's value. 77 | func (g *StandardGauge) Update(v int64) { 78 | atomic.StoreInt64(&g.value, v) 79 | } 80 | 81 | // Value returns the gauge's current value. 82 | func (g *StandardGauge) Value() int64 { 83 | return atomic.LoadInt64(&g.value) 84 | } 85 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/gauge_float64.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "sync" 4 | 5 | // GaugeFloat64s hold a float64 value that can be set arbitrarily. 6 | type GaugeFloat64 interface { 7 | Snapshot() GaugeFloat64 8 | Update(float64) 9 | Value() float64 10 | } 11 | 12 | // GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a 13 | // new StandardGaugeFloat64. 14 | func GetOrRegisterGaugeFloat64(name string, r Registry) GaugeFloat64 { 15 | if nil == r { 16 | r = DefaultRegistry 17 | } 18 | return r.GetOrRegister(name, NewGaugeFloat64()).(GaugeFloat64) 19 | } 20 | 21 | // NewGaugeFloat64 constructs a new StandardGaugeFloat64. 22 | func NewGaugeFloat64() GaugeFloat64 { 23 | if UseNilMetrics { 24 | return NilGaugeFloat64{} 25 | } 26 | return &StandardGaugeFloat64{ 27 | value: 0.0, 28 | } 29 | } 30 | 31 | // NewRegisteredGaugeFloat64 constructs and registers a new StandardGaugeFloat64. 32 | func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 { 33 | c := NewGaugeFloat64() 34 | if nil == r { 35 | r = DefaultRegistry 36 | } 37 | r.Register(name, c) 38 | return c 39 | } 40 | 41 | // GaugeFloat64Snapshot is a read-only copy of another GaugeFloat64. 42 | type GaugeFloat64Snapshot float64 43 | 44 | // Snapshot returns the snapshot. 45 | func (g GaugeFloat64Snapshot) Snapshot() GaugeFloat64 { return g } 46 | 47 | // Update panics. 48 | func (GaugeFloat64Snapshot) Update(float64) { 49 | panic("Update called on a GaugeFloat64Snapshot") 50 | } 51 | 52 | // Value returns the value at the time the snapshot was taken. 53 | func (g GaugeFloat64Snapshot) Value() float64 { return float64(g) } 54 | 55 | // NilGauge is a no-op Gauge. 56 | type NilGaugeFloat64 struct{} 57 | 58 | // Snapshot is a no-op. 59 | func (NilGaugeFloat64) Snapshot() GaugeFloat64 { return NilGaugeFloat64{} } 60 | 61 | // Update is a no-op. 62 | func (NilGaugeFloat64) Update(v float64) {} 63 | 64 | // Value is a no-op. 65 | func (NilGaugeFloat64) Value() float64 { return 0.0 } 66 | 67 | // StandardGaugeFloat64 is the standard implementation of a GaugeFloat64 and uses 68 | // sync.Mutex to manage a single float64 value. 69 | type StandardGaugeFloat64 struct { 70 | mutex sync.Mutex 71 | value float64 72 | } 73 | 74 | // Snapshot returns a read-only copy of the gauge. 75 | func (g *StandardGaugeFloat64) Snapshot() GaugeFloat64 { 76 | return GaugeFloat64Snapshot(g.Value()) 77 | } 78 | 79 | // Update updates the gauge's value. 80 | func (g *StandardGaugeFloat64) Update(v float64) { 81 | g.mutex.Lock() 82 | defer g.mutex.Unlock() 83 | g.value = v 84 | } 85 | 86 | // Value returns the gauge's current value. 87 | func (g *StandardGaugeFloat64) Value() float64 { 88 | g.mutex.Lock() 89 | defer g.mutex.Unlock() 90 | return g.value 91 | } 92 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/gauge_float64_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "testing" 4 | 5 | func BenchmarkGuageFloat64(b *testing.B) { 6 | g := NewGaugeFloat64() 7 | b.ResetTimer() 8 | for i := 0; i < b.N; i++ { 9 | g.Update(float64(i)) 10 | } 11 | } 12 | 13 | func TestGaugeFloat64(t *testing.T) { 14 | g := NewGaugeFloat64() 15 | g.Update(float64(47.0)) 16 | if v := g.Value(); float64(47.0) != v { 17 | t.Errorf("g.Value(): 47.0 != %v\n", v) 18 | } 19 | } 20 | 21 | func TestGaugeFloat64Snapshot(t *testing.T) { 22 | g := NewGaugeFloat64() 23 | g.Update(float64(47.0)) 24 | snapshot := g.Snapshot() 25 | g.Update(float64(0)) 26 | if v := snapshot.Value(); float64(47.0) != v { 27 | t.Errorf("g.Value(): 47.0 != %v\n", v) 28 | } 29 | } 30 | 31 | func TestGetOrRegisterGaugeFloat64(t *testing.T) { 32 | r := NewRegistry() 33 | NewRegisteredGaugeFloat64("foo", r).Update(float64(47.0)) 34 | t.Logf("registry: %v", r) 35 | if g := GetOrRegisterGaugeFloat64("foo", r); float64(47.0) != g.Value() { 36 | t.Fatal(g) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/gauge_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "testing" 4 | 5 | func BenchmarkGuage(b *testing.B) { 6 | g := NewGauge() 7 | b.ResetTimer() 8 | for i := 0; i < b.N; i++ { 9 | g.Update(int64(i)) 10 | } 11 | } 12 | 13 | func TestGauge(t *testing.T) { 14 | g := NewGauge() 15 | g.Update(int64(47)) 16 | if v := g.Value(); 47 != v { 17 | t.Errorf("g.Value(): 47 != %v\n", v) 18 | } 19 | } 20 | 21 | func TestGaugeSnapshot(t *testing.T) { 22 | g := NewGauge() 23 | g.Update(int64(47)) 24 | snapshot := g.Snapshot() 25 | g.Update(int64(0)) 26 | if v := snapshot.Value(); 47 != v { 27 | t.Errorf("g.Value(): 47 != %v\n", v) 28 | } 29 | } 30 | 31 | func TestGetOrRegisterGauge(t *testing.T) { 32 | r := NewRegistry() 33 | NewRegisteredGauge("foo", r).Update(47) 34 | if g := GetOrRegisterGauge("foo", r); 47 != g.Value() { 35 | t.Fatal(g) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "net" 5 | "time" 6 | ) 7 | 8 | func ExampleGraphite() { 9 | addr, _ := net.ResolveTCPAddr("net", ":2003") 10 | go Graphite(DefaultRegistry, 1*time.Second, "some.prefix", addr) 11 | } 12 | 13 | func ExampleGraphiteWithConfig() { 14 | addr, _ := net.ResolveTCPAddr("net", ":2003") 15 | go GraphiteWithConfig(GraphiteConfig{ 16 | Addr: addr, 17 | Registry: DefaultRegistry, 18 | FlushInterval: 1 * time.Second, 19 | DurationUnit: time.Millisecond, 20 | Percentiles: []float64{ 0.5, 0.75, 0.99, 0.999 }, 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/healthcheck.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | // Healthchecks hold an error value describing an arbitrary up/down status. 4 | type Healthcheck interface { 5 | Check() 6 | Error() error 7 | Healthy() 8 | Unhealthy(error) 9 | } 10 | 11 | // NewHealthcheck constructs a new Healthcheck which will use the given 12 | // function to update its status. 13 | func NewHealthcheck(f func(Healthcheck)) Healthcheck { 14 | if UseNilMetrics { 15 | return NilHealthcheck{} 16 | } 17 | return &StandardHealthcheck{nil, f} 18 | } 19 | 20 | // NilHealthcheck is a no-op. 21 | type NilHealthcheck struct{} 22 | 23 | // Check is a no-op. 24 | func (NilHealthcheck) Check() {} 25 | 26 | // Error is a no-op. 27 | func (NilHealthcheck) Error() error { return nil } 28 | 29 | // Healthy is a no-op. 30 | func (NilHealthcheck) Healthy() {} 31 | 32 | // Unhealthy is a no-op. 33 | func (NilHealthcheck) Unhealthy(error) {} 34 | 35 | // StandardHealthcheck is the standard implementation of a Healthcheck and 36 | // stores the status and a function to call to update the status. 37 | type StandardHealthcheck struct { 38 | err error 39 | f func(Healthcheck) 40 | } 41 | 42 | // Check runs the healthcheck function to update the healthcheck's status. 43 | func (h *StandardHealthcheck) Check() { 44 | h.f(h) 45 | } 46 | 47 | // Error returns the healthcheck's status, which will be nil if it is healthy. 48 | func (h *StandardHealthcheck) Error() error { 49 | return h.err 50 | } 51 | 52 | // Healthy marks the healthcheck as healthy. 53 | func (h *StandardHealthcheck) Healthy() { 54 | h.err = nil 55 | } 56 | 57 | // Unhealthy marks the healthcheck as unhealthy. The error is stored and 58 | // may be retrieved by the Error method. 59 | func (h *StandardHealthcheck) Unhealthy(err error) { 60 | h.err = err 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/histogram_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "testing" 4 | 5 | func BenchmarkHistogram(b *testing.B) { 6 | h := NewHistogram(NewUniformSample(100)) 7 | b.ResetTimer() 8 | for i := 0; i < b.N; i++ { 9 | h.Update(int64(i)) 10 | } 11 | } 12 | 13 | func TestGetOrRegisterHistogram(t *testing.T) { 14 | r := NewRegistry() 15 | s := NewUniformSample(100) 16 | NewRegisteredHistogram("foo", r, s).Update(47) 17 | if h := GetOrRegisterHistogram("foo", r, s); 1 != h.Count() { 18 | t.Fatal(h) 19 | } 20 | } 21 | 22 | func TestHistogram10000(t *testing.T) { 23 | h := NewHistogram(NewUniformSample(100000)) 24 | for i := 1; i <= 10000; i++ { 25 | h.Update(int64(i)) 26 | } 27 | testHistogram10000(t, h) 28 | } 29 | 30 | func TestHistogramEmpty(t *testing.T) { 31 | h := NewHistogram(NewUniformSample(100)) 32 | if count := h.Count(); 0 != count { 33 | t.Errorf("h.Count(): 0 != %v\n", count) 34 | } 35 | if min := h.Min(); 0 != min { 36 | t.Errorf("h.Min(): 0 != %v\n", min) 37 | } 38 | if max := h.Max(); 0 != max { 39 | t.Errorf("h.Max(): 0 != %v\n", max) 40 | } 41 | if mean := h.Mean(); 0.0 != mean { 42 | t.Errorf("h.Mean(): 0.0 != %v\n", mean) 43 | } 44 | if stdDev := h.StdDev(); 0.0 != stdDev { 45 | t.Errorf("h.StdDev(): 0.0 != %v\n", stdDev) 46 | } 47 | ps := h.Percentiles([]float64{0.5, 0.75, 0.99}) 48 | if 0.0 != ps[0] { 49 | t.Errorf("median: 0.0 != %v\n", ps[0]) 50 | } 51 | if 0.0 != ps[1] { 52 | t.Errorf("75th percentile: 0.0 != %v\n", ps[1]) 53 | } 54 | if 0.0 != ps[2] { 55 | t.Errorf("99th percentile: 0.0 != %v\n", ps[2]) 56 | } 57 | } 58 | 59 | func TestHistogramSnapshot(t *testing.T) { 60 | h := NewHistogram(NewUniformSample(100000)) 61 | for i := 1; i <= 10000; i++ { 62 | h.Update(int64(i)) 63 | } 64 | snapshot := h.Snapshot() 65 | h.Update(0) 66 | testHistogram10000(t, snapshot) 67 | } 68 | 69 | func testHistogram10000(t *testing.T, h Histogram) { 70 | if count := h.Count(); 10000 != count { 71 | t.Errorf("h.Count(): 10000 != %v\n", count) 72 | } 73 | if min := h.Min(); 1 != min { 74 | t.Errorf("h.Min(): 1 != %v\n", min) 75 | } 76 | if max := h.Max(); 10000 != max { 77 | t.Errorf("h.Max(): 10000 != %v\n", max) 78 | } 79 | if mean := h.Mean(); 5000.5 != mean { 80 | t.Errorf("h.Mean(): 5000.5 != %v\n", mean) 81 | } 82 | if stdDev := h.StdDev(); 2886.751331514372 != stdDev { 83 | t.Errorf("h.StdDev(): 2886.751331514372 != %v\n", stdDev) 84 | } 85 | ps := h.Percentiles([]float64{0.5, 0.75, 0.99}) 86 | if 5000.5 != ps[0] { 87 | t.Errorf("median: 5000.5 != %v\n", ps[0]) 88 | } 89 | if 7500.75 != ps[1] { 90 | t.Errorf("75th percentile: 7500.75 != %v\n", ps[1]) 91 | } 92 | if 9900.99 != ps[2] { 93 | t.Errorf("99th percentile: 9900.99 != %v\n", ps[2]) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/json.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "time" 7 | ) 8 | 9 | // MarshalJSON returns a byte slice containing a JSON representation of all 10 | // the metrics in the Registry. 11 | func (r StandardRegistry) MarshalJSON() ([]byte, error) { 12 | data := make(map[string]map[string]interface{}) 13 | r.Each(func(name string, i interface{}) { 14 | values := make(map[string]interface{}) 15 | switch metric := i.(type) { 16 | case Counter: 17 | values["count"] = metric.Count() 18 | case Gauge: 19 | values["value"] = metric.Value() 20 | case GaugeFloat64: 21 | values["value"] = metric.Value() 22 | case Healthcheck: 23 | values["error"] = nil 24 | metric.Check() 25 | if err := metric.Error(); nil != err { 26 | values["error"] = metric.Error().Error() 27 | } 28 | case Histogram: 29 | h := metric.Snapshot() 30 | ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 31 | values["count"] = h.Count() 32 | values["min"] = h.Min() 33 | values["max"] = h.Max() 34 | values["mean"] = h.Mean() 35 | values["stddev"] = h.StdDev() 36 | values["median"] = ps[0] 37 | values["75%"] = ps[1] 38 | values["95%"] = ps[2] 39 | values["99%"] = ps[3] 40 | values["99.9%"] = ps[4] 41 | case Meter: 42 | m := metric.Snapshot() 43 | values["count"] = m.Count() 44 | values["1m.rate"] = m.Rate1() 45 | values["5m.rate"] = m.Rate5() 46 | values["15m.rate"] = m.Rate15() 47 | values["mean.rate"] = m.RateMean() 48 | case Timer: 49 | t := metric.Snapshot() 50 | ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 51 | values["count"] = t.Count() 52 | values["min"] = t.Min() 53 | values["max"] = t.Max() 54 | values["mean"] = t.Mean() 55 | values["stddev"] = t.StdDev() 56 | values["median"] = ps[0] 57 | values["75%"] = ps[1] 58 | values["95%"] = ps[2] 59 | values["99%"] = ps[3] 60 | values["99.9%"] = ps[4] 61 | values["1m.rate"] = t.Rate1() 62 | values["5m.rate"] = t.Rate5() 63 | values["15m.rate"] = t.Rate15() 64 | values["mean.rate"] = t.RateMean() 65 | } 66 | data[name] = values 67 | }) 68 | return json.Marshal(data) 69 | } 70 | 71 | // WriteJSON writes metrics from the given registry periodically to the 72 | // specified io.Writer as JSON. 73 | func WriteJSON(r Registry, d time.Duration, w io.Writer) { 74 | for _ = range time.Tick(d) { 75 | WriteJSONOnce(r, w) 76 | } 77 | } 78 | 79 | // WriteJSONOnce writes metrics from the given registry to the specified 80 | // io.Writer as JSON. 81 | func WriteJSONOnce(r Registry, w io.Writer) { 82 | json.NewEncoder(w).Encode(r) 83 | } 84 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/json_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "testing" 7 | ) 8 | 9 | func TestRegistryMarshallJSON(t *testing.T) { 10 | b := &bytes.Buffer{} 11 | enc := json.NewEncoder(b) 12 | r := NewRegistry() 13 | r.Register("counter", NewCounter()) 14 | enc.Encode(r) 15 | if s := b.String(); "{\"counter\":{\"count\":0}}\n" != s { 16 | t.Fatalf(s) 17 | } 18 | } 19 | 20 | func TestRegistryWriteJSONOnce(t *testing.T) { 21 | r := NewRegistry() 22 | r.Register("counter", NewCounter()) 23 | b := &bytes.Buffer{} 24 | WriteJSONOnce(r, b) 25 | if s := b.String(); s != "{\"counter\":{\"count\":0}}\n" { 26 | t.Fail() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/client.go: -------------------------------------------------------------------------------- 1 | package librato 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | ) 10 | 11 | const Operations = "operations" 12 | const OperationsShort = "ops" 13 | 14 | type LibratoClient struct { 15 | Email, Token string 16 | } 17 | 18 | // property strings 19 | const ( 20 | // display attributes 21 | Color = "color" 22 | DisplayMax = "display_max" 23 | DisplayMin = "display_min" 24 | DisplayUnitsLong = "display_units_long" 25 | DisplayUnitsShort = "display_units_short" 26 | DisplayStacked = "display_stacked" 27 | DisplayTransform = "display_transform" 28 | // special gauge display attributes 29 | SummarizeFunction = "summarize_function" 30 | Aggregate = "aggregate" 31 | 32 | // metric keys 33 | Name = "name" 34 | Period = "period" 35 | Description = "description" 36 | DisplayName = "display_name" 37 | Attributes = "attributes" 38 | 39 | // measurement keys 40 | MeasureTime = "measure_time" 41 | Source = "source" 42 | Value = "value" 43 | 44 | // special gauge keys 45 | Count = "count" 46 | Sum = "sum" 47 | Max = "max" 48 | Min = "min" 49 | SumSquares = "sum_squares" 50 | 51 | // batch keys 52 | Counters = "counters" 53 | Gauges = "gauges" 54 | 55 | MetricsPostUrl = "https://metrics-api.librato.com/v1/metrics" 56 | ) 57 | 58 | type Measurement map[string]interface{} 59 | type Metric map[string]interface{} 60 | 61 | type Batch struct { 62 | Gauges []Measurement `json:"gauges,omitempty"` 63 | Counters []Measurement `json:"counters,omitempty"` 64 | MeasureTime int64 `json:"measure_time"` 65 | Source string `json:"source"` 66 | } 67 | 68 | func (self *LibratoClient) PostMetrics(batch Batch) (err error) { 69 | var ( 70 | js []byte 71 | req *http.Request 72 | resp *http.Response 73 | ) 74 | 75 | if len(batch.Counters) == 0 && len(batch.Gauges) == 0 { 76 | return nil 77 | } 78 | 79 | if js, err = json.Marshal(batch); err != nil { 80 | return 81 | } 82 | 83 | if req, err = http.NewRequest("POST", MetricsPostUrl, bytes.NewBuffer(js)); err != nil { 84 | return 85 | } 86 | 87 | req.Header.Set("Content-Type", "application/json") 88 | req.SetBasicAuth(self.Email, self.Token) 89 | 90 | if resp, err = http.DefaultClient.Do(req); err != nil { 91 | return 92 | } 93 | 94 | if resp.StatusCode != http.StatusOK { 95 | var body []byte 96 | if body, err = ioutil.ReadAll(resp.Body); err != nil { 97 | body = []byte(fmt.Sprintf("(could not fetch response body for error: %s)", err)) 98 | } 99 | err = fmt.Errorf("Unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body)) 100 | } 101 | return 102 | } 103 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/log.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "log" 5 | "time" 6 | ) 7 | 8 | // Output each metric in the given registry periodically using the given 9 | // logger. 10 | func Log(r Registry, d time.Duration, l *log.Logger) { 11 | for _ = range time.Tick(d) { 12 | r.Each(func(name string, i interface{}) { 13 | switch metric := i.(type) { 14 | case Counter: 15 | l.Printf("counter %s\n", name) 16 | l.Printf(" count: %9d\n", metric.Count()) 17 | case Gauge: 18 | l.Printf("gauge %s\n", name) 19 | l.Printf(" value: %9d\n", metric.Value()) 20 | case GaugeFloat64: 21 | l.Printf("gauge %s\n", name) 22 | l.Printf(" value: %f\n", metric.Value()) 23 | case Healthcheck: 24 | metric.Check() 25 | l.Printf("healthcheck %s\n", name) 26 | l.Printf(" error: %v\n", metric.Error()) 27 | case Histogram: 28 | h := metric.Snapshot() 29 | ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 30 | l.Printf("histogram %s\n", name) 31 | l.Printf(" count: %9d\n", h.Count()) 32 | l.Printf(" min: %9d\n", h.Min()) 33 | l.Printf(" max: %9d\n", h.Max()) 34 | l.Printf(" mean: %12.2f\n", h.Mean()) 35 | l.Printf(" stddev: %12.2f\n", h.StdDev()) 36 | l.Printf(" median: %12.2f\n", ps[0]) 37 | l.Printf(" 75%%: %12.2f\n", ps[1]) 38 | l.Printf(" 95%%: %12.2f\n", ps[2]) 39 | l.Printf(" 99%%: %12.2f\n", ps[3]) 40 | l.Printf(" 99.9%%: %12.2f\n", ps[4]) 41 | case Meter: 42 | m := metric.Snapshot() 43 | l.Printf("meter %s\n", name) 44 | l.Printf(" count: %9d\n", m.Count()) 45 | l.Printf(" 1-min rate: %12.2f\n", m.Rate1()) 46 | l.Printf(" 5-min rate: %12.2f\n", m.Rate5()) 47 | l.Printf(" 15-min rate: %12.2f\n", m.Rate15()) 48 | l.Printf(" mean rate: %12.2f\n", m.RateMean()) 49 | case Timer: 50 | t := metric.Snapshot() 51 | ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 52 | l.Printf("timer %s\n", name) 53 | l.Printf(" count: %9d\n", t.Count()) 54 | l.Printf(" min: %9d\n", t.Min()) 55 | l.Printf(" max: %9d\n", t.Max()) 56 | l.Printf(" mean: %12.2f\n", t.Mean()) 57 | l.Printf(" stddev: %12.2f\n", t.StdDev()) 58 | l.Printf(" median: %12.2f\n", ps[0]) 59 | l.Printf(" 75%%: %12.2f\n", ps[1]) 60 | l.Printf(" 95%%: %12.2f\n", ps[2]) 61 | l.Printf(" 99%%: %12.2f\n", ps[3]) 62 | l.Printf(" 99.9%%: %12.2f\n", ps[4]) 63 | l.Printf(" 1-min rate: %12.2f\n", t.Rate1()) 64 | l.Printf(" 5-min rate: %12.2f\n", t.Rate5()) 65 | l.Printf(" 15-min rate: %12.2f\n", t.Rate15()) 66 | l.Printf(" mean rate: %12.2f\n", t.RateMean()) 67 | } 68 | }) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/meter_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func BenchmarkMeter(b *testing.B) { 9 | m := NewMeter() 10 | b.ResetTimer() 11 | for i := 0; i < b.N; i++ { 12 | m.Mark(1) 13 | } 14 | } 15 | 16 | func TestGetOrRegisterMeter(t *testing.T) { 17 | r := NewRegistry() 18 | NewRegisteredMeter("foo", r).Mark(47) 19 | if m := GetOrRegisterMeter("foo", r); 47 != m.Count() { 20 | t.Fatal(m) 21 | } 22 | } 23 | 24 | func TestMeterDecay(t *testing.T) { 25 | ma := meterArbiter{ 26 | ticker: time.NewTicker(1), 27 | } 28 | m := newStandardMeter() 29 | ma.meters = append(ma.meters, m) 30 | go ma.tick() 31 | m.Mark(1) 32 | rateMean := m.RateMean() 33 | time.Sleep(1) 34 | if m.RateMean() >= rateMean { 35 | t.Error("m.RateMean() didn't decrease") 36 | } 37 | } 38 | 39 | func TestMeterNonzero(t *testing.T) { 40 | m := NewMeter() 41 | m.Mark(3) 42 | if count := m.Count(); 3 != count { 43 | t.Errorf("m.Count(): 3 != %v\n", count) 44 | } 45 | } 46 | 47 | func TestMeterSnapshot(t *testing.T) { 48 | m := NewMeter() 49 | m.Mark(1) 50 | if snapshot := m.Snapshot(); m.RateMean() != snapshot.RateMean() { 51 | t.Fatal(snapshot) 52 | } 53 | } 54 | 55 | func TestMeterZero(t *testing.T) { 56 | m := NewMeter() 57 | if count := m.Count(); 0 != count { 58 | t.Errorf("m.Count(): 0 != %v\n", count) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/metrics.go: -------------------------------------------------------------------------------- 1 | // Go port of Coda Hale's Metrics library 2 | // 3 | // 4 | // 5 | // Coda Hale's original work: 6 | package metrics 7 | 8 | // UseNilMetrics is checked by the constructor functions for all of the 9 | // standard metrics. If it is true, the metric returned is a stub. 10 | // 11 | // This global kill-switch helps quantify the observer effect and makes 12 | // for less cluttered pprof profiles. 13 | var UseNilMetrics bool = false 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "sync" 7 | "testing" 8 | ) 9 | 10 | const FANOUT = 128 11 | 12 | // Stop the compiler from complaining during debugging. 13 | var ( 14 | _ = ioutil.Discard 15 | _ = log.LstdFlags 16 | ) 17 | 18 | func BenchmarkMetrics(b *testing.B) { 19 | r := NewRegistry() 20 | c := NewRegisteredCounter("counter", r) 21 | g := NewRegisteredGauge("gauge", r) 22 | gf := NewRegisteredGaugeFloat64("gaugefloat64", r) 23 | h := NewRegisteredHistogram("histogram", r, NewUniformSample(100)) 24 | m := NewRegisteredMeter("meter", r) 25 | t := NewRegisteredTimer("timer", r) 26 | RegisterDebugGCStats(r) 27 | RegisterRuntimeMemStats(r) 28 | b.ResetTimer() 29 | ch := make(chan bool) 30 | 31 | wgD := &sync.WaitGroup{} 32 | /* 33 | wgD.Add(1) 34 | go func() { 35 | defer wgD.Done() 36 | //log.Println("go CaptureDebugGCStats") 37 | for { 38 | select { 39 | case <-ch: 40 | //log.Println("done CaptureDebugGCStats") 41 | return 42 | default: 43 | CaptureDebugGCStatsOnce(r) 44 | } 45 | } 46 | }() 47 | //*/ 48 | 49 | wgR := &sync.WaitGroup{} 50 | //* 51 | wgR.Add(1) 52 | go func() { 53 | defer wgR.Done() 54 | //log.Println("go CaptureRuntimeMemStats") 55 | for { 56 | select { 57 | case <-ch: 58 | //log.Println("done CaptureRuntimeMemStats") 59 | return 60 | default: 61 | CaptureRuntimeMemStatsOnce(r) 62 | } 63 | } 64 | }() 65 | //*/ 66 | 67 | wgW := &sync.WaitGroup{} 68 | /* 69 | wgW.Add(1) 70 | go func() { 71 | defer wgW.Done() 72 | //log.Println("go Write") 73 | for { 74 | select { 75 | case <-ch: 76 | //log.Println("done Write") 77 | return 78 | default: 79 | WriteOnce(r, ioutil.Discard) 80 | } 81 | } 82 | }() 83 | //*/ 84 | 85 | wg := &sync.WaitGroup{} 86 | wg.Add(FANOUT) 87 | for i := 0; i < FANOUT; i++ { 88 | go func(i int) { 89 | defer wg.Done() 90 | //log.Println("go", i) 91 | for i := 0; i < b.N; i++ { 92 | c.Inc(1) 93 | g.Update(int64(i)) 94 | gf.Update(float64(i)) 95 | h.Update(int64(i)) 96 | m.Mark(1) 97 | t.Update(1) 98 | } 99 | //log.Println("done", i) 100 | }(i) 101 | } 102 | wg.Wait() 103 | close(ch) 104 | wgD.Wait() 105 | wgR.Wait() 106 | wgW.Wait() 107 | } 108 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "net" 5 | "time" 6 | ) 7 | 8 | func ExampleOpenTSDB() { 9 | addr, _ := net.ResolveTCPAddr("net", ":2003") 10 | go OpenTSDB(DefaultRegistry, 1*time.Second, "some.prefix", addr) 11 | } 12 | 13 | func ExampleOpenTSDBWithConfig() { 14 | addr, _ := net.ResolveTCPAddr("net", ":2003") 15 | go OpenTSDBWithConfig(OpenTSDBConfig{ 16 | Addr: addr, 17 | Registry: DefaultRegistry, 18 | FlushInterval: 1 * time.Second, 19 | DurationUnit: time.Millisecond, 20 | }) 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/registry_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "testing" 4 | 5 | func BenchmarkRegistry(b *testing.B) { 6 | r := NewRegistry() 7 | r.Register("foo", NewCounter()) 8 | b.ResetTimer() 9 | for i := 0; i < b.N; i++ { 10 | r.Each(func(string, interface{}) {}) 11 | } 12 | } 13 | 14 | func TestRegistry(t *testing.T) { 15 | r := NewRegistry() 16 | r.Register("foo", NewCounter()) 17 | i := 0 18 | r.Each(func(name string, iface interface{}) { 19 | i++ 20 | if "foo" != name { 21 | t.Fatal(name) 22 | } 23 | if _, ok := iface.(Counter); !ok { 24 | t.Fatal(iface) 25 | } 26 | }) 27 | if 1 != i { 28 | t.Fatal(i) 29 | } 30 | r.Unregister("foo") 31 | i = 0 32 | r.Each(func(string, interface{}) { i++ }) 33 | if 0 != i { 34 | t.Fatal(i) 35 | } 36 | } 37 | 38 | func TestRegistryDuplicate(t *testing.T) { 39 | r := NewRegistry() 40 | if err := r.Register("foo", NewCounter()); nil != err { 41 | t.Fatal(err) 42 | } 43 | if err := r.Register("foo", NewGauge()); nil == err { 44 | t.Fatal(err) 45 | } 46 | i := 0 47 | r.Each(func(name string, iface interface{}) { 48 | i++ 49 | if _, ok := iface.(Counter); !ok { 50 | t.Fatal(iface) 51 | } 52 | }) 53 | if 1 != i { 54 | t.Fatal(i) 55 | } 56 | } 57 | 58 | func TestRegistryGet(t *testing.T) { 59 | r := NewRegistry() 60 | r.Register("foo", NewCounter()) 61 | if count := r.Get("foo").(Counter).Count(); 0 != count { 62 | t.Fatal(count) 63 | } 64 | r.Get("foo").(Counter).Inc(1) 65 | if count := r.Get("foo").(Counter).Count(); 1 != count { 66 | t.Fatal(count) 67 | } 68 | } 69 | 70 | func TestRegistryGetOrRegister(t *testing.T) { 71 | r := NewRegistry() 72 | 73 | // First metric wins with GetOrRegister 74 | _ = r.GetOrRegister("foo", NewCounter()) 75 | m := r.GetOrRegister("foo", NewGauge()) 76 | if _, ok := m.(Counter); !ok { 77 | t.Fatal(m) 78 | } 79 | 80 | i := 0 81 | r.Each(func(name string, iface interface{}) { 82 | i++ 83 | if name != "foo" { 84 | t.Fatal(name) 85 | } 86 | if _, ok := iface.(Counter); !ok { 87 | t.Fatal(iface) 88 | } 89 | }) 90 | if i != 1 { 91 | t.Fatal(i) 92 | } 93 | } 94 | 95 | func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) { 96 | r := NewRegistry() 97 | 98 | // First metric wins with GetOrRegister 99 | _ = r.GetOrRegister("foo", NewCounter) 100 | m := r.GetOrRegister("foo", NewGauge) 101 | if _, ok := m.(Counter); !ok { 102 | t.Fatal(m) 103 | } 104 | 105 | i := 0 106 | r.Each(func(name string, iface interface{}) { 107 | i++ 108 | if name != "foo" { 109 | t.Fatal(name) 110 | } 111 | if _, ok := iface.(Counter); !ok { 112 | t.Fatal(iface) 113 | } 114 | }) 115 | if i != 1 { 116 | t.Fatal(i) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/runtime_cgo.go: -------------------------------------------------------------------------------- 1 | // +build cgo 2 | 3 | package metrics 4 | 5 | import "runtime" 6 | 7 | func numCgoCall() int64 { 8 | return runtime.NumCgoCall() 9 | } 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/runtime_no_cgo.go: -------------------------------------------------------------------------------- 1 | // +build !cgo 2 | 3 | package metrics 4 | 5 | func numCgoCall() int64 { 6 | return 0 7 | } 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/runtime_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "runtime" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func BenchmarkRuntimeMemStats(b *testing.B) { 10 | r := NewRegistry() 11 | RegisterRuntimeMemStats(r) 12 | b.ResetTimer() 13 | for i := 0; i < b.N; i++ { 14 | CaptureRuntimeMemStatsOnce(r) 15 | } 16 | } 17 | 18 | func TestRuntimeMemStats(t *testing.T) { 19 | r := NewRegistry() 20 | RegisterRuntimeMemStats(r) 21 | CaptureRuntimeMemStatsOnce(r) 22 | zero := runtimeMetrics.MemStats.PauseNs.Count() // Get a "zero" since GC may have run before these tests. 23 | runtime.GC() 24 | CaptureRuntimeMemStatsOnce(r) 25 | if count := runtimeMetrics.MemStats.PauseNs.Count(); 1 != count-zero { 26 | t.Fatal(count - zero) 27 | } 28 | runtime.GC() 29 | runtime.GC() 30 | CaptureRuntimeMemStatsOnce(r) 31 | if count := runtimeMetrics.MemStats.PauseNs.Count(); 3 != count-zero { 32 | t.Fatal(count - zero) 33 | } 34 | for i := 0; i < 256; i++ { 35 | runtime.GC() 36 | } 37 | CaptureRuntimeMemStatsOnce(r) 38 | if count := runtimeMetrics.MemStats.PauseNs.Count(); 259 != count-zero { 39 | t.Fatal(count - zero) 40 | } 41 | for i := 0; i < 257; i++ { 42 | runtime.GC() 43 | } 44 | CaptureRuntimeMemStatsOnce(r) 45 | if count := runtimeMetrics.MemStats.PauseNs.Count(); 515 != count-zero { // We lost one because there were too many GCs between captures. 46 | t.Fatal(count - zero) 47 | } 48 | } 49 | 50 | func TestRuntimeMemStatsBlocking(t *testing.T) { 51 | if g := runtime.GOMAXPROCS(0); g < 2 { 52 | t.Skipf("skipping TestRuntimeMemStatsBlocking with GOMAXPROCS=%d\n", g) 53 | } 54 | ch := make(chan int) 55 | go testRuntimeMemStatsBlocking(ch) 56 | var memStats runtime.MemStats 57 | t0 := time.Now() 58 | runtime.ReadMemStats(&memStats) 59 | t1 := time.Now() 60 | t.Log("i++ during runtime.ReadMemStats:", <-ch) 61 | go testRuntimeMemStatsBlocking(ch) 62 | d := t1.Sub(t0) 63 | t.Log(d) 64 | time.Sleep(d) 65 | t.Log("i++ during time.Sleep:", <-ch) 66 | } 67 | 68 | func testRuntimeMemStatsBlocking(ch chan int) { 69 | i := 0 70 | for { 71 | select { 72 | case ch <- i: 73 | return 74 | default: 75 | i++ 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/syslog.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package metrics 4 | 5 | import ( 6 | "fmt" 7 | "log/syslog" 8 | "time" 9 | ) 10 | 11 | // Output each metric in the given registry to syslog periodically using 12 | // the given syslogger. 13 | func Syslog(r Registry, d time.Duration, w *syslog.Writer) { 14 | for _ = range time.Tick(d) { 15 | r.Each(func(name string, i interface{}) { 16 | switch metric := i.(type) { 17 | case Counter: 18 | w.Info(fmt.Sprintf("counter %s: count: %d", name, metric.Count())) 19 | case Gauge: 20 | w.Info(fmt.Sprintf("gauge %s: value: %d", name, metric.Value())) 21 | case GaugeFloat64: 22 | w.Info(fmt.Sprintf("gauge %s: value: %f", name, metric.Value())) 23 | case Healthcheck: 24 | metric.Check() 25 | w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, metric.Error())) 26 | case Histogram: 27 | h := metric.Snapshot() 28 | ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 29 | w.Info(fmt.Sprintf( 30 | "histogram %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f", 31 | name, 32 | h.Count(), 33 | h.Min(), 34 | h.Max(), 35 | h.Mean(), 36 | h.StdDev(), 37 | ps[0], 38 | ps[1], 39 | ps[2], 40 | ps[3], 41 | ps[4], 42 | )) 43 | case Meter: 44 | m := metric.Snapshot() 45 | w.Info(fmt.Sprintf( 46 | "meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f", 47 | name, 48 | m.Count(), 49 | m.Rate1(), 50 | m.Rate5(), 51 | m.Rate15(), 52 | m.RateMean(), 53 | )) 54 | case Timer: 55 | t := metric.Snapshot() 56 | ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 57 | w.Info(fmt.Sprintf( 58 | "timer %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f 1-min: %.2f 5-min: %.2f 15-min: %.2f mean-rate: %.2f", 59 | name, 60 | t.Count(), 61 | t.Min(), 62 | t.Max(), 63 | t.Mean(), 64 | t.StdDev(), 65 | ps[0], 66 | ps[1], 67 | ps[2], 68 | ps[3], 69 | ps[4], 70 | t.Rate1(), 71 | t.Rate5(), 72 | t.Rate15(), 73 | t.RateMean(), 74 | )) 75 | } 76 | }) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/timer_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "math" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func BenchmarkTimer(b *testing.B) { 10 | tm := NewTimer() 11 | b.ResetTimer() 12 | for i := 0; i < b.N; i++ { 13 | tm.Update(1) 14 | } 15 | } 16 | 17 | func TestGetOrRegisterTimer(t *testing.T) { 18 | r := NewRegistry() 19 | NewRegisteredTimer("foo", r).Update(47) 20 | if tm := GetOrRegisterTimer("foo", r); 1 != tm.Count() { 21 | t.Fatal(tm) 22 | } 23 | } 24 | 25 | func TestTimerExtremes(t *testing.T) { 26 | tm := NewTimer() 27 | tm.Update(math.MaxInt64) 28 | tm.Update(0) 29 | if stdDev := tm.StdDev(); 4.611686018427388e+18 != stdDev { 30 | t.Errorf("tm.StdDev(): 4.611686018427388e+18 != %v\n", stdDev) 31 | } 32 | } 33 | 34 | func TestTimerFunc(t *testing.T) { 35 | tm := NewTimer() 36 | tm.Time(func() { time.Sleep(50e6) }) 37 | if max := tm.Max(); 45e6 > max || max > 55e6 { 38 | t.Errorf("tm.Max(): 45e6 > %v || %v > 55e6\n", max, max) 39 | } 40 | } 41 | 42 | func TestTimerZero(t *testing.T) { 43 | tm := NewTimer() 44 | if count := tm.Count(); 0 != count { 45 | t.Errorf("tm.Count(): 0 != %v\n", count) 46 | } 47 | if min := tm.Min(); 0 != min { 48 | t.Errorf("tm.Min(): 0 != %v\n", min) 49 | } 50 | if max := tm.Max(); 0 != max { 51 | t.Errorf("tm.Max(): 0 != %v\n", max) 52 | } 53 | if mean := tm.Mean(); 0.0 != mean { 54 | t.Errorf("tm.Mean(): 0.0 != %v\n", mean) 55 | } 56 | if stdDev := tm.StdDev(); 0.0 != stdDev { 57 | t.Errorf("tm.StdDev(): 0.0 != %v\n", stdDev) 58 | } 59 | ps := tm.Percentiles([]float64{0.5, 0.75, 0.99}) 60 | if 0.0 != ps[0] { 61 | t.Errorf("median: 0.0 != %v\n", ps[0]) 62 | } 63 | if 0.0 != ps[1] { 64 | t.Errorf("75th percentile: 0.0 != %v\n", ps[1]) 65 | } 66 | if 0.0 != ps[2] { 67 | t.Errorf("99th percentile: 0.0 != %v\n", ps[2]) 68 | } 69 | if rate1 := tm.Rate1(); 0.0 != rate1 { 70 | t.Errorf("tm.Rate1(): 0.0 != %v\n", rate1) 71 | } 72 | if rate5 := tm.Rate5(); 0.0 != rate5 { 73 | t.Errorf("tm.Rate5(): 0.0 != %v\n", rate5) 74 | } 75 | if rate15 := tm.Rate15(); 0.0 != rate15 { 76 | t.Errorf("tm.Rate15(): 0.0 != %v\n", rate15) 77 | } 78 | if rateMean := tm.RateMean(); 0.0 != rateMean { 79 | t.Errorf("tm.RateMean(): 0.0 != %v\n", rateMean) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/rcrowley/go-metrics/writer_test.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "sort" 5 | "testing" 6 | ) 7 | 8 | func TestMetricsSorting(t *testing.T) { 9 | var namedMetrics = namedMetricSlice{ 10 | {name: "zzz"}, 11 | {name: "bbb"}, 12 | {name: "fff"}, 13 | {name: "ggg"}, 14 | } 15 | 16 | sort.Sort(namedMetrics) 17 | for i, name := range []string{"bbb", "fff", "ggg", "zzz"} { 18 | if namedMetrics[i].name != name { 19 | t.Fail() 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gorouter 2 | ========== 3 | 4 | 从CloudFoundry gorouter(tag 45ca951297) fork,更改实现。 5 | 6 | 主要修改点: 7 | CloudFoundry gorouter通过侦听NATS汇报的信息生成路由表; 8 | 而现在gorouter去redis里读取相应信息生成路由表(gorouter会在内存中保存份路由表,如果redis宕掉将暂停更新路由表)。 9 | 10 | router启动时,从redis中加载路由表(URL与rs\_ip:port的对应关系,以及CNAME与URL的对应关系),格式如 11 | 12 | ``` 13 | redis 127.0.0.1:6379> keys * 14 | 1) "/rs/demo.xae.xiaomi.com" 15 | 3) "/rs/test.xae.xiaomi.com" 16 | 4) "/cname/ulricqin.com" 17 | 6) "/rs/api2.xae.xiaomi.com" 18 | redis 127.0.0.1:6379> lrange /rs/demo.xae.xiaomi.com 0 -1 19 | 1) "10.201.37.5:10005" 20 | 2) "10.201.37.5:10004" 21 | redis 127.0.0.1:6379> get /cname/ulricqin.com 22 | "/rs/demo.xae.xiaomi.com" 23 | ``` 24 | 25 | 每隔reload_uri_interval(单位s,默认5s),从redis重新加载路由表 26 | 27 | ## 配置项说明 28 | 29 | - **redis_server**: DINP server模块的redis server地址 30 | - **reload_uri_interval**: 更新路由表的周期,单位s (默认5s) 31 | 其它配置项与安装同CloudFoundry gorouter。 32 | -------------------------------------------------------------------------------- /access_log/access_log_record.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "time" 9 | 10 | "github.com/dinp/gorouter/route" 11 | ) 12 | 13 | type AccessLogRecord struct { 14 | Request *http.Request 15 | StatusCode int 16 | RouteEndpoint *route.Endpoint 17 | StartedAt time.Time 18 | FirstByteAt time.Time 19 | FinishedAt time.Time 20 | BodyBytesSent int64 21 | } 22 | 23 | func (r *AccessLogRecord) FormatStartedAt() string { 24 | return r.StartedAt.Format("02/01/2006:15:04:05 -0700") 25 | } 26 | 27 | func (r *AccessLogRecord) FormatRequestHeader(k string) (v string) { 28 | v = r.Request.Header.Get(k) 29 | if v == "" { 30 | v = "-" 31 | } 32 | return 33 | } 34 | 35 | func (r *AccessLogRecord) ResponseTime() float64 { 36 | return float64(r.FinishedAt.UnixNano()-r.StartedAt.UnixNano()) / float64(time.Second) 37 | } 38 | 39 | func (r *AccessLogRecord) makeRecord() *bytes.Buffer { 40 | b := &bytes.Buffer{} 41 | fmt.Fprintf(b, `%s - `, r.Request.Host) 42 | fmt.Fprintf(b, `[%s] `, r.FormatStartedAt()) 43 | fmt.Fprintf(b, `"%s %s %s" `, r.Request.Method, r.Request.URL.RequestURI(), r.Request.Proto) 44 | 45 | if r.StatusCode == 0 { 46 | fmt.Fprintf(b, "MissingResponseStatusCode ") 47 | } else { 48 | fmt.Fprintf(b, `%d `, r.StatusCode) 49 | } 50 | 51 | fmt.Fprintf(b, `%d `, r.BodyBytesSent) 52 | fmt.Fprintf(b, `"%s" `, r.FormatRequestHeader("Referer")) 53 | fmt.Fprintf(b, `"%s" `, r.FormatRequestHeader("User-Agent")) 54 | fmt.Fprintf(b, `%s `, r.Request.RemoteAddr) 55 | fmt.Fprintf(b, `x_forwarded_for:"%s" `, r.FormatRequestHeader("X-Forwarded-For")) 56 | fmt.Fprintf(b, `vcap_request_id:%s `, r.FormatRequestHeader("X-Vcap-Request-Id")) 57 | 58 | if r.ResponseTime() < 0 { 59 | fmt.Fprintf(b, "response_time:MissingFinishedAt ") 60 | } else { 61 | fmt.Fprintf(b, `response_time:%.9f `, r.ResponseTime()) 62 | } 63 | 64 | if r.RouteEndpoint == nil { 65 | fmt.Fprintf(b, "app_id:MissingRouteEndpointApplicationId") 66 | } else { 67 | fmt.Fprintf(b, `app_id:%s`, r.RouteEndpoint.CanonicalAddr()) 68 | } 69 | 70 | fmt.Fprint(b, "\n") 71 | return b 72 | } 73 | 74 | func (r *AccessLogRecord) WriteTo(w io.Writer) (int64, error) { 75 | recordBuffer := r.makeRecord() 76 | return recordBuffer.WriteTo(w) 77 | } 78 | 79 | func (r *AccessLogRecord) ApplicationId() string { 80 | if r.RouteEndpoint == nil { 81 | return "" 82 | } 83 | 84 | return r.RouteEndpoint.CanonicalAddr() 85 | } 86 | 87 | func (r *AccessLogRecord) LogMessage() string { 88 | if r.ApplicationId() == "" { 89 | return "" 90 | } 91 | 92 | recordBuffer := r.makeRecord() 93 | return recordBuffer.String() 94 | } 95 | -------------------------------------------------------------------------------- /access_log/access_logger.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | type AccessLogger interface { 4 | Run() 5 | Stop() 6 | Log(record AccessLogRecord) 7 | } 8 | -------------------------------------------------------------------------------- /access_log/create_running_access_logger.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | import ( 4 | steno "github.com/cloudfoundry/gosteno" 5 | "github.com/dinp/gorouter/config" 6 | "strconv" 7 | 8 | "os" 9 | ) 10 | 11 | func CreateRunningAccessLogger(config *config.Config) (AccessLogger, error) { 12 | 13 | if config.AccessLog == "" && !config.Logging.LoggregatorEnabled { 14 | return &NullAccessLogger{}, nil 15 | } 16 | 17 | logger := steno.NewLogger("access_log") 18 | 19 | var err error 20 | var file *os.File 21 | if config.AccessLog != "" { 22 | file, err = os.OpenFile(config.AccessLog, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) 23 | if err != nil { 24 | logger.Errorf("Error creating accesslog file, %s: (%s)", config.AccessLog, err.Error()) 25 | return nil, err 26 | } 27 | } 28 | 29 | var dropsondeSourceInstance string 30 | if config.Logging.LoggregatorEnabled { 31 | dropsondeSourceInstance = strconv.FormatUint(uint64(config.Index), 10) 32 | } 33 | 34 | accessLogger := NewFileAndLoggregatorAccessLogger(file, dropsondeSourceInstance) 35 | go accessLogger.Run() 36 | return accessLogger, nil 37 | } 38 | -------------------------------------------------------------------------------- /access_log/file_and_loggregator_access_logger.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | import ( 4 | "io" 5 | "regexp" 6 | 7 | "github.com/cloudfoundry/dropsonde/autowire/logs" 8 | ) 9 | 10 | type FileAndLoggregatorAccessLogger struct { 11 | dropsondeSourceInstance string 12 | channel chan AccessLogRecord 13 | stopCh chan struct{} 14 | writer io.Writer 15 | } 16 | 17 | func NewFileAndLoggregatorAccessLogger(f io.Writer, dropsondeSourceInstance string) *FileAndLoggregatorAccessLogger { 18 | a := &FileAndLoggregatorAccessLogger{ 19 | dropsondeSourceInstance: dropsondeSourceInstance, 20 | writer: f, 21 | channel: make(chan AccessLogRecord, 128), 22 | stopCh: make(chan struct{}), 23 | } 24 | 25 | return a 26 | } 27 | 28 | func (x *FileAndLoggregatorAccessLogger) Run() { 29 | for { 30 | select { 31 | case record := <-x.channel: 32 | if x.writer != nil { 33 | record.WriteTo(x.writer) 34 | } 35 | 36 | if x.dropsondeSourceInstance != "" && record.ApplicationId() != "" { 37 | logs.SendAppLog(record.ApplicationId(), record.LogMessage(), "RTR", x.dropsondeSourceInstance) 38 | } 39 | case <-x.stopCh: 40 | return 41 | } 42 | } 43 | } 44 | 45 | func (x *FileAndLoggregatorAccessLogger) FileWriter() io.Writer { 46 | return x.writer 47 | } 48 | 49 | func (x *FileAndLoggregatorAccessLogger) DropsondeSourceInstance() string { 50 | return x.dropsondeSourceInstance 51 | } 52 | 53 | func (x *FileAndLoggregatorAccessLogger) Stop() { 54 | close(x.stopCh) 55 | } 56 | 57 | func (x *FileAndLoggregatorAccessLogger) Log(r AccessLogRecord) { 58 | x.channel <- r 59 | } 60 | 61 | var ipAddressRegex, _ = regexp.Compile(`^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:[0-9]{1,5}){1}$`) 62 | var hostnameRegex, _ = regexp.Compile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])(:[0-9]{1,5}){1}$`) 63 | 64 | func isValidUrl(url string) bool { 65 | return ipAddressRegex.MatchString(url) || hostnameRegex.MatchString(url) 66 | } 67 | -------------------------------------------------------------------------------- /access_log/null_access_logger.go: -------------------------------------------------------------------------------- 1 | package access_log 2 | 3 | type NullAccessLogger struct { 4 | } 5 | 6 | func (x *NullAccessLogger) Run() {} 7 | func (x *NullAccessLogger) Stop() {} 8 | func (x *NullAccessLogger) Log(AccessLogRecord) {} 9 | -------------------------------------------------------------------------------- /common/common.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "net" 5 | "strconv" 6 | 7 | "github.com/nu7hatch/gouuid" 8 | steno "github.com/cloudfoundry/gosteno" 9 | ) 10 | 11 | var log = steno.NewLogger("common.logger") 12 | 13 | func LocalIP() (string, error) { 14 | addr, err := net.ResolveUDPAddr("udp", "1.2.3.4:1") 15 | if err != nil { 16 | return "", err 17 | } 18 | 19 | conn, err := net.DialUDP("udp", nil, addr) 20 | if err != nil { 21 | return "", err 22 | } 23 | 24 | defer conn.Close() 25 | 26 | host, _, err := net.SplitHostPort(conn.LocalAddr().String()) 27 | if err != nil { 28 | return "", err 29 | } 30 | 31 | return host, nil 32 | } 33 | 34 | func GrabEphemeralPort() (port uint16, err error) { 35 | var listener net.Listener 36 | var portStr string 37 | var p int 38 | 39 | listener, err = net.Listen("tcp", ":0") 40 | if err != nil { 41 | return 42 | } 43 | defer listener.Close() 44 | 45 | _, portStr, err = net.SplitHostPort(listener.Addr().String()) 46 | if err != nil { 47 | return 48 | } 49 | 50 | p, err = strconv.Atoi(portStr) 51 | port = uint16(p) 52 | 53 | return 54 | } 55 | 56 | func GenerateUUID() (string, error) { 57 | uuid, err := uuid.NewV4() 58 | if err != nil { 59 | return "", err 60 | } 61 | return uuid.String(), nil 62 | } 63 | -------------------------------------------------------------------------------- /common/duration.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | type Duration time.Duration 11 | 12 | func (d Duration) MarshalJSON() ([]byte, error) { 13 | ds := formatDuration(time.Duration(d)) 14 | return []byte(fmt.Sprintf(`"%s"`, ds)), nil 15 | } 16 | 17 | func (d *Duration) UnmarshalJSON(b []byte) error { 18 | str := strings.Trim(string(b), "\"") 19 | u := strings.Split(str, ":") 20 | 21 | ds := u[0] 22 | di, err := strconv.ParseInt(ds[:len(ds)-1], 10, 64) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | hs := u[1] 28 | hi, err := strconv.ParseInt(hs[:len(hs)-1], 10, 64) 29 | if err != nil { 30 | return err 31 | } 32 | 33 | hi += di * 24 34 | 35 | u[1] = fmt.Sprintf("%dh", hi) 36 | 37 | dur, err := time.ParseDuration(strings.Join(u[1:], "")) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | *d = Duration(dur) 43 | return nil 44 | } 45 | 46 | func formatDuration(d time.Duration) string { 47 | t := int64(d.Seconds()) 48 | day := t / (60 * 60 * 24) 49 | t = t % (60 * 60 * 24) 50 | hour := t / (60 * 60) 51 | t = t % (60 * 60) 52 | min := t / 60 53 | sec := t % 60 54 | 55 | ds := fmt.Sprintf("%dd:%dh:%dm:%ds", day, hour, min, sec) 56 | return ds 57 | } 58 | 59 | type Time time.Time 60 | 61 | func (t Time) MarshalJSON() ([]byte, error) { 62 | f := "2006-01-02 15:04:05 -0700" 63 | s := time.Time(t).Format(f) 64 | return []byte(fmt.Sprintf(`"%s"`, s)), nil 65 | } 66 | 67 | func (t *Time) UnmarshalJSON(b []byte) error { 68 | s := string(b) 69 | f := `"2006-01-02 15:04:05 -0700"` 70 | 71 | tt, err := time.Parse(f, s) 72 | if err != nil { 73 | return err 74 | } 75 | 76 | *t = Time(tt) 77 | return nil 78 | } 79 | 80 | func (t Time) Elapsed() Duration { 81 | d := time.Since(time.Time(t)) 82 | return Duration(d) 83 | } 84 | -------------------------------------------------------------------------------- /common/healthz.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type Healthz struct { 4 | } 5 | 6 | func (v *Healthz) Value() string { 7 | return "ok" 8 | } 9 | -------------------------------------------------------------------------------- /common/http/basic_auth.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | "net/http" 7 | "strings" 8 | ) 9 | 10 | type Authenticator func(user, password string) bool 11 | 12 | type BasicAuth struct { 13 | http.Handler 14 | Authenticator 15 | } 16 | 17 | func extractCredentials(req *http.Request) []string { 18 | x := strings.Split(req.Header.Get("Authorization"), " ") 19 | if len(x) != 2 || x[0] != "Basic" { 20 | return nil 21 | } 22 | 23 | y, err := base64.StdEncoding.DecodeString(x[1]) 24 | if err != nil { 25 | return nil 26 | } 27 | 28 | z := strings.Split(string(y), ":") 29 | if len(z) != 2 { 30 | return nil 31 | } 32 | 33 | return z 34 | } 35 | 36 | func (x *BasicAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) { 37 | y := extractCredentials(req) 38 | // Beware of the hack 39 | if req.URL.Path != "/healthz" && (y == nil || !x.Authenticator(y[0], y[1])) { 40 | w.Header().Set("WWW-Authenticate", "Basic") 41 | w.WriteHeader(http.StatusUnauthorized) 42 | w.Write([]byte(fmt.Sprintf("%d Unauthorized\n", http.StatusUnauthorized))) 43 | } else { 44 | x.Handler.ServeHTTP(w, req) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/http/headers.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | const ( 4 | VcapBackendHeader = "X-Vcap-Backend" 5 | CfRouteEndpointHeader = "X-Cf-RouteEndpoint" 6 | VcapRouterHeader = "X-Vcap-Router" 7 | VcapRequestIdHeader = "X-Vcap-Request-Id" 8 | VcapTraceHeader = "X-Vcap-Trace" 9 | CfInstanceIdHeader = "X-CF-InstanceID" 10 | ) 11 | -------------------------------------------------------------------------------- /common/log_counter.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "sync" 6 | 7 | steno "github.com/cloudfoundry/gosteno" 8 | ) 9 | 10 | type LogCounter struct { 11 | sync.Mutex 12 | counts map[string]int 13 | } 14 | 15 | func NewLogCounter() *LogCounter { 16 | lc := &LogCounter{ 17 | counts: make(map[string]int), 18 | } 19 | return lc 20 | } 21 | 22 | func (lc *LogCounter) AddRecord(record *steno.Record) { 23 | lc.Lock() 24 | lc.counts[record.Level.Name] += 1 25 | lc.Unlock() 26 | } 27 | 28 | func (lc *LogCounter) GetCount(key string) int { 29 | lc.Lock() 30 | defer lc.Unlock() 31 | return lc.counts[key] 32 | } 33 | 34 | func (lc *LogCounter) Flush() {} 35 | func (lc *LogCounter) SetCodec(codec steno.Codec) {} 36 | 37 | func (lc *LogCounter) GetCodec() steno.Codec { 38 | return nil 39 | } 40 | 41 | func (lc *LogCounter) MarshalJSON() ([]byte, error) { 42 | lc.Lock() 43 | defer lc.Unlock() 44 | return json.Marshal(lc.counts) 45 | } 46 | -------------------------------------------------------------------------------- /common/process_status.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "sync" 5 | "syscall" 6 | "time" 7 | ) 8 | 9 | const RefreshInterval time.Duration = time.Second * 1 10 | 11 | type ProcessStatus struct { 12 | sync.RWMutex 13 | rusage *syscall.Rusage 14 | lastCpuTime int64 15 | stopSignal chan bool 16 | stopped bool 17 | 18 | CpuUsage float64 19 | MemRss int64 20 | } 21 | 22 | func NewProcessStatus() *ProcessStatus { 23 | p := new(ProcessStatus) 24 | p.rusage = new(syscall.Rusage) 25 | 26 | go func() { 27 | timer := time.Tick(RefreshInterval) 28 | for { 29 | select { 30 | case <-timer: 31 | p.Update() 32 | case <-p.stopSignal: 33 | return 34 | } 35 | } 36 | }() 37 | 38 | return p 39 | } 40 | 41 | func (p *ProcessStatus) Update() { 42 | e := syscall.Getrusage(syscall.RUSAGE_SELF, p.rusage) 43 | if e != nil { 44 | log.Fatal(e.Error()) 45 | } 46 | 47 | p.Lock() 48 | defer p.Unlock() 49 | p.MemRss = int64(p.rusage.Maxrss) 50 | 51 | t := p.rusage.Utime.Nano() + p.rusage.Stime.Nano() 52 | p.CpuUsage = float64(t-p.lastCpuTime) / float64(RefreshInterval.Nanoseconds()) 53 | p.lastCpuTime = t 54 | } 55 | 56 | func (p *ProcessStatus) StopUpdate() { 57 | p.Lock() 58 | defer p.Unlock() 59 | if !p.stopped { 60 | p.stopped = true 61 | p.stopSignal <- true 62 | p.stopSignal = nil 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /common/spec/component.go: -------------------------------------------------------------------------------- 1 | package spec 2 | 3 | type Component interface { 4 | Start() error 5 | Stop() 6 | Running() bool 7 | } 8 | -------------------------------------------------------------------------------- /common/varz.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "sync" 6 | ) 7 | 8 | type GenericVarz struct { 9 | // Static common metrics 10 | NumCores int `json:"num_cores"` 11 | 12 | // Dynamic common metrics 13 | MemStat int64 `json:"mem"` 14 | Cpu float64 `json:"cpu"` 15 | 16 | Uptime Duration `json:"uptime"` 17 | LogCounts *LogCounter `json:"log_counts"` 18 | } 19 | 20 | type Varz struct { 21 | sync.Mutex 22 | GenericVarz 23 | UniqueVarz interface{} // Every component's unique metrics 24 | 25 | component VcapComponent 26 | } 27 | 28 | func transform(x interface{}, y *map[string]interface{}) error { 29 | var b []byte 30 | var err error 31 | 32 | b, err = json.Marshal(x) 33 | if err != nil { 34 | return err 35 | } 36 | 37 | err = json.Unmarshal(b, y) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | return nil 43 | } 44 | 45 | func (v *Varz) MarshalJSON() ([]byte, error) { 46 | r := make(map[string]interface{}) 47 | 48 | var err error 49 | 50 | err = transform(v.UniqueVarz, &r) 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | err = transform(v.GenericVarz, &r) 56 | if err != nil { 57 | return nil, err 58 | } 59 | 60 | err = transform(v.component, &r) 61 | if err != nil { 62 | return nil, err 63 | } 64 | 65 | return json.Marshal(r) 66 | } 67 | -------------------------------------------------------------------------------- /example_config/example.yml: -------------------------------------------------------------------------------- 1 | #config/router.yml 2 | status: 3 | port: 8082 4 | user: router 5 | pass: routerPass 6 | 7 | logging: 8 | file: router.log 9 | syslog: 10 | level: debug 11 | 12 | port: 8888 13 | index: 0 14 | 15 | pidfile: router.pid 16 | go_max_procs: 8 17 | 18 | redis_server: "127.0.0.1:6379" 19 | reload_uri_interval: 5 20 | -------------------------------------------------------------------------------- /proxy/responsewriter.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type proxyResponseWriter struct { 8 | w http.ResponseWriter 9 | status int 10 | size int 11 | 12 | flusher http.Flusher 13 | done bool 14 | } 15 | 16 | func newProxyResponseWriter(w http.ResponseWriter) *proxyResponseWriter { 17 | proxyWriter := &proxyResponseWriter{ 18 | w: w, 19 | flusher: w.(http.Flusher), 20 | } 21 | 22 | return proxyWriter 23 | } 24 | 25 | func (p *proxyResponseWriter) Header() http.Header { 26 | return p.w.Header() 27 | } 28 | 29 | func (p *proxyResponseWriter) Write(b []byte) (int, error) { 30 | if p.done { 31 | return 0, nil 32 | } 33 | 34 | if p.status == 0 { 35 | p.WriteHeader(http.StatusOK) 36 | } 37 | size, err := p.w.Write(b) 38 | p.size += size 39 | return size, err 40 | } 41 | 42 | func (p *proxyResponseWriter) WriteHeader(s int) { 43 | if p.done { 44 | return 45 | } 46 | 47 | p.w.WriteHeader(s) 48 | 49 | if p.status == 0 { 50 | p.status = s 51 | } 52 | } 53 | 54 | func (p *proxyResponseWriter) Done() { 55 | p.done = true 56 | } 57 | 58 | func (p *proxyResponseWriter) Flush() { 59 | if p.flusher != nil { 60 | p.flusher.Flush() 61 | } 62 | } 63 | 64 | func (p *proxyResponseWriter) Status() int { 65 | return p.status 66 | } 67 | 68 | func (p *proxyResponseWriter) Size() int { 69 | return p.size 70 | } 71 | -------------------------------------------------------------------------------- /route/endpoint.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | func NewEndpoint(host string, port uint16, tags map[string]string) *Endpoint { 9 | return &Endpoint{ 10 | addr: fmt.Sprintf("%s:%d", host, port), 11 | Tags: tags, 12 | } 13 | } 14 | 15 | type Endpoint struct { 16 | addr string 17 | Tags map[string]string 18 | } 19 | 20 | func (e *Endpoint) MarshalJSON() ([]byte, error) { 21 | return json.Marshal(e.addr) 22 | } 23 | 24 | func (e *Endpoint) CanonicalAddr() string { 25 | return e.addr 26 | } 27 | 28 | func (e *Endpoint) ToLogData() interface{} { 29 | return struct { 30 | Addr string 31 | Tags map[string]string 32 | }{ 33 | e.addr, 34 | e.Tags, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /route/uris.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type Uri string 8 | 9 | func (u Uri) ToLower() Uri { 10 | return Uri(strings.ToLower(string(u))) 11 | } 12 | -------------------------------------------------------------------------------- /stats/heap.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | type HeapType interface { 4 | SetIndex(i, j int) 5 | } 6 | 7 | type Heap struct { 8 | HeapType 9 | h []interface{} 10 | } 11 | 12 | func (x *Heap) Len() int { 13 | return len(x.h) 14 | } 15 | 16 | func (x *Heap) Swap(i, j int) { 17 | x.h[i], x.h[j] = x.h[j], x.h[i] 18 | x.SetIndex(i, i) 19 | x.SetIndex(j, j) 20 | } 21 | 22 | func (x *Heap) Push(a interface{}) { 23 | x.h = append(x.h, a) 24 | n := len(x.h) 25 | x.SetIndex(n-1, n-1) 26 | } 27 | 28 | func (x *Heap) Pop() interface{} { 29 | n := len(x.h) 30 | x.SetIndex(n-1, -1) 31 | y := x.h[n-1] 32 | x.h = x.h[0 : n-1] 33 | return y 34 | } 35 | 36 | func (x *Heap) Copy() Heap { 37 | y := *x 38 | y.h = make([]interface{}, len(x.h)) 39 | copy(y.h, x.h) 40 | return y 41 | } 42 | --------------------------------------------------------------------------------