Ein vollständig vorgestellter Riemann -Kunde, der auf der Zuverlässigkeit von Poolboy und der fantastischen Kraft von Elixir basiert!
Riemannx ist ein in Elixir gebauter Riemann -Client. Derzeit ist es der einzige Kunde in Elixir, der UDP und TLS (sowie TCP) unterstützt. Es gibt auch einen Batching -Modus, den Sie verwenden können, der mit einem der Transporte funktioniert.
Es verfügt über eine experimentelle kombinierte Option, die das Beste aus TCP und UDP macht. Im kombinierten Modus ist UDP der bevorzugte Ansatz. Wenn die Meldungsgröße jedoch den maximalen UDP -Größensatz überschreitet, wird TCP verwendet.
Wie immer sind Voraussetzungen vor der Verwendung von Riemannx erforderlich, die meisten davon sind offensichtlich (Elixir, Erlang), enthalten jedoch einige Informationen darüber, welche Versionen getestet und unterstützt werden.
Derzeit werden alle Erlang -Versionen ~> 18 unterstützt. Dies beinhaltet 20, 20.1, die noch nicht getestet werden, aber ich habe dort keine großen Probleme vorhaben.
Getestet von Travis:
18.019.320.0Ich habe versucht, die Kompatibilität ab 1.3.4 zu gewährleisten, und ich werde dies gegebenenfalls weiterhin tun. Getestete Kombinationen:
18.0 Elixier: 1.3.4 / 1.4.5 / 1.5.119.3 Elixier: 1.3.4 / 1.4.5 / 1.5.120.0 Elixier: 1.4.5 / 1.5.1Wie so oft ist ein Client ohne ITS -Server -Gegenstück ziemlich nutzlos - weitere Informationen zu Riemann finden Sie unter http://riemann.io.
Der Kunde wurde nur gegen: 0.2.11 getestet. Aus Version 4.0.0 des Clients müssen Sie use_micro auf False festlegen, wenn Sie eine Version von Riemann älter als 0.2.13 verwenden und das Zeitfeld nicht selbst festlegen. Es sollte mit 0.3.0 funktionieren, wurde aber früher noch nicht getestet (jeder, der an Integrationstests arbeiten möchte, würde ich es sehr zu schätzen wissen).
Die Installation erfolgt genau wie in jeder anderen Elixierbibliothek. Fügen Sie sie Ihrer Mix -Datei hinzu und der Rest ist der Verlauf:
def deps do
[ { :riemannx , "~> 4.0" } ]
endStellen Sie sicher, dass Sie Riemannx in Ihre MIX.EXS -Datei zur Anwendungsliste hinzufügen. Dies stellt sicher, dass sie mit Ihrer App gestartet wird und in Ihren Veröffentlichungen enthalten ist (wenn Sie einen Release -Manager verwenden):
applications : [ :logger , :riemannx ] Um Riemannx zu verwenden, müssen Sie nur einige Konfigurationseinträge ausfüllen - danach passiert alles einfach automatisch (speichern Sie natürlich das tatsächliche Senden). Im Folgenden finden Sie eine umfassende Liste der verfügbaren Optionen:
config :riemannx , [
host: "localhost" , # The riemann server
event_host: "my_app" , # You can override the host name sent to riemann if you want (see: Host Injection)
send_timeout: 30_000 , # Synchronous send timeout
checkout_timeout: 30_000 , # Timeout for checking out a poolboy worker
type: :batch , # The type of connection you want to run (:tcp, :udp, :tls, :combined, :batch)
settings_module: Riemannx.Settings.Default # The backend used for reading settings back
metrics_module: Riemannx . Metrics.Default # The backend used for sending metrics
use_micro: true # Set to false if you use a riemann version before 0.2.13
batch_settings: [
type : :combined # The underlying connection to use when using batching.
size: 50 , # The size of batches to send to riemann.
interval: { 1 , :seconds } , # The interval at which to send batches.
limit: :infinity # The max limit of batches allowed in the batching queue
]
tcp: [
port : 5555 ,
retry_count: 5 , # How many times to re-attempt a TCP connection
retry_interval: 1000 , # Interval to wait before the next TCP connection attempt (milliseconds).
priority: :high , # Priority to give TCP workers.
options: [ ] , # Specify additional options to be passed to gen_tcp (NOTE: [:binary, nodelay: true, packet: 4, active: true] will be added to whatever you type here as they are deemed essential)
pool_size: 5 , # How many TCP workers should be in the pool.
max_overflow: 5 , # Under heavy load how many more TCP workers can be created to meet demand?
strategy: :fifo # The poolboy strategy for retrieving workers from the queue
] ,
udp: [
port: 5555 ,
priority: :high ,
options: [ ] , # Specify additional options to be passed to gen_udp (NOTE: [:binary, sndbuf: max_udp_size()] will be added to whatever you type here as they are deemed essential)
max_size: 16_384 , # Maximum accepted packet size (this is configured in your Riemann server)
pool_size: 5 ,
max_overflow: 5 ,
strategy: :fifo
] ,
tls: [
port: 5554 ,
retry_count: 5 , # How many times to re-attempt a TLS connection
retry_interval: 1000 , # Interval to wait before the next TLS connection attempt (milliseconds).
priority: :high ,
options: [ ] , # Specify additional options to be passed to :ssl (NOTE: [:binary, nodelay: true, packet: 4, active: true] will be added to whatever you type here as they are deemed essential)
pool_size: 5 ,
max_overflow: 5 ,
strategy: :fifo
]
] Riemannx unterstützt zwei send -Methoden, eine asynchron, die andere Synchron:
Mit der synchronen Senden können Sie die Fehler verarbeiten, die während des Sendens auftreten können. Im Folgenden zeigt ein Beispiel, wie dieser Fehler aussieht und was bei einem erfolgreichen Senden passiert:
event = [ service: "riemannx-elixir" ,
metric: 1 ,
attributes: [ a: 1 ] ,
description: "test" ]
case Riemannx . send ( event ) do
:ok ->
"Success!"
[ error: error , msg: encoded_msg ] ->
# The error will always be a string so you can output it as it is.
#
# The encoded message is a binary blob but you can use the riemannx proto
# msg module to decode it if you wish to see it in human readable form.
msg = encoded_msg |> Riemannx.Proto.Msg . decode ( )
Logger . warn ( "Error: #{ error } Message: #{ inspect msg } " )
endAsynchrones Senden ist viel schneller, aber Sie wissen nie wirklich, ob Ihre Nachricht es geschafft hat. In vielen Fällen ist diese Art des Sendens sicher genug und für die meisten Anwendungsfälle die empfohlene Auswahl. Es ist ziemlich einfach zu implementieren:
event = [ service: "riemannx-elixir" ,
metric: 1 ,
attributes: [ a: 1 ] ,
description: "test" ]
Riemannx . send_async ( event )
# Who knows if it made it? Who cares? 60% of the time it works everytime!Hinweis: Wenn ein Arbeiter es nicht senden kann, stirbt und neu gestartet wird und ihm die Möglichkeit gibt, in einen „korrekten“ Zustand zurückzukehren. Bei einem asynchronen Senden erfolgt dies durch Muster -Matching: OK mit dem Befehl Senden, für synchronen Senden, wenn der Rückgabewert ein Fehler ist, töten wir den Arbeiter, bevor wir das Ergebnis zurückgeben.
Mit dem TLS -Support können Sie eine sichere TCP -Verbindung mit Ihrem Riemann -Server verwenden, um mehr darüber zu erfahren
Wenn Sie TLS verwenden, verwenden Sie ein reines TCP -Setup, kombiniert mit TLS nicht unterstützt (und sollte es auch nicht sein):
config :riemannx , [
host: "127.0.0.1" ,
type: :tls ,
tls: [
port: 5554 ,
retry_count: 5 , # How many times to re-attempt a TLS connection
retry_interval: 1000 , # Interval to wait before the next TLS connection attempt (milliseconds).
priority: :high ,
# SSL Opts are passed to the underlying ssl erlang interface
# See available options here: http://erlang.org/doc/man/ssl.html
# (NOTE: [:binary, nodelay: true, packet: 4, active: true] will be added to whatever you type here as they are deemed essential)
options: [
keyfile: "path/to/key" ,
certfile: "path/to/cert" ,
verify_peer: true
] ,
pool_size: 5 ,
max_overflow: 5 ,
strategy: :fifo
]
]Angenommen, Sie haben die serverseitig korrekt eingerichtet, sollte dies alles sein, was Sie für den Einstieg benötigen.
Riemann hat das Konzept eines abfragbaren Index, mit dem Sie nach bestimmten Ereignissen suchen können. Indexen müssen speziell in Ihrer Konfiguration erstellt werden, da sonst der Server einen "No Index" -Fehler zurückgibt.
# Lets send an event that we can then query
Riemannx . send ( [ service: "riemannx" , metric: 5.0 , attributes: [ v: "2.2.0" ] ] )
# Let's fish it out
events = Riemannx . query ( 'service ~= "riemannx"' )
# [%{attributes: %{"v" => "2.2.0"}, description: nil, host: _,
# metric: nil, service: "riemannx", state: nil, tags: [],
# time: _, ttl: _}]Weitere Informationen zu Abfragen und den Sprachmerkmalen finden Sie in den Kernkonzepten.
Dieser Abschnitt enthält einige Hinweise zum Verhalten von Riemannx, die Sie interessieren oder Fragen zu bestimmten Dingen beantworten können.
Das Stapel von 4,0.0 ist das Standardverbindungsverhalten - die Standard -Stapelgröße beträgt 50 und das Intervall beträgt alle 1 Sekunde. Batching funktioniert wie so:
Was auch immer in der Warteschlange ist, wird in jedem Intervall gesendet.
Wenn die Größe der Warteschlange die festgelegte Stapelgröße erreicht, wird sie unabhängig vom Intervall gespült.
Stapel werden fallen gelassen, wenn keine Arbeiter zur Verfügung stehen, um die checkout_timer zu :infinity
Es gibt einen neuen Typ mit dem Namen :batch und eine Einstellungsschlüssel mit dem Namen batch_settings: In Batch_Settings können Sie einen Typ für die zugrunde liegende Verbindung angeben ( :tcp , :udp ,: :combined ,: :tls ). Wie immer kombiniert ist der Standard.
Optional kann eine Stapelgrenznummer angegeben werden ( :limit ). Wenn festgelegt wird, dass die Batching -Warteschlange die angegebene Menge an Chargen hat, werden die Ereignisse von Batch_Size aus limit * batch_size gesendet, bis mindestens eine Charge gesendet wird. Standardwert ist :infinity
Aus Version 0.2.13 von Riemann Es war möglich, Zeit in Mikrosekunden festzulegen - Riemannx unterstützt und verwendet das Feld time_micros (es sei denn, Sie haben das Feld TIME oder TIME_MICROS selbst festgelegt. Riemannx überschreibt das nicht). Wenn Sie eine ältere Version von Riemann verwenden, verwendet sie nur das Feld Sekunden.
Hinweis: Wenn Sie sowohl Zeit- als auch Time_Micros -Riemann festlegen, priorisieren Sie die Mikrozeit, und Riemannx überschreibt auch nicht.
Es klingt schicker als es ist, beschreibt aber im Grunde die Funktionalität, die Ihrem Ereignis einen Host -Eintrag hinzufügt, wenn Sie keine angegeben haben. Es gibt 3 Möglichkeiten, einen Host anzugeben:
Tun Sie es, bevor Sie das Ereignis senden (Fügen Sie der Schlüsselwortliste einen: Host -Schlüssel hinzu).
Fügen Sie die Taste :event_host zu Ihrer Konfiguration hinzu.
Lassen Sie es riemannx mit :inet.gethostname() tun - wir nennen das nur einmal und speichern das Ergebnis, es wird nicht jedes Ereignis aufgerufen.
Die letzten 2 Optionen sind am günstigsten, da sie Ihren Code sauber halten.
In diesem Kunden besteht die Möglichkeit, Ihren Mitarbeitern eine Priorität zu setzen, damit Sie die Sende Ihrer Statistiken an Riemann höher oder weniger Priorität haben können.
Die Differenzierung einer Priorität hängt stark von der Hardware ab und wie Sie Ihre anderen Prioritäten im Allgemeinen festgelegt haben. Weitere Informationen finden Sie hier: http://erlang.org/doc/man/erlang.html#process_flag-2
Wenn Sie versuchen, die Priorität festzulegen, wird: Max Riemannx einen RuntimeError erhöht, da dies eine schreckliche Idee ist. Es wird auch einen RuntimeError erhöhen, wenn Sie es versuchen: Foo, weil das auch eine schreckliche Idee ist.
Die Migration auf 3.0 ist im Wesentlichen nur ein Fall der Änderung Ihres Konfigurationslayouts - alle dieselben Optionen, außer jetzt haben Sie mehr Kontrolle über Ihre Arbeiter auf Typ -Ebene. Dies ist besonders wertvoll, wenn Sie das kombinierte Setup verwenden, wie Sie können, beispielsweise einen kleineren Pool von TCP -Mitarbeitern und einen größeren UDP -Arbeiterpool, anstatt wie vor dem (2x, was auch immer Sie angegeben haben).
Sie können dieses neue Layout hier sehen: Konfiguration
Wenn hier etwas nicht sinnvoll ist, können Sie ein Problem frei eröffnen, damit wir die Readme erweitern können, um die Unklarheit zu beheben.
Wenn Sie Ihre Einstellungen an anderer Stelle speichern möchten, können Sie beispielsweise ein Backend zum Lesen von Einstellungen aus einer Datenbank erstellen. Sehen Sie sich das Modul für die Standardeinstellungsmodul für die erforderlichen Rückrufe an.
Dies kann nützlich sein, wenn Sie unternehmensweite Einstellungen an einem Ort speichern möchten.
Fühlen Sie sich frei, ein Problem zu eröffnen, wenn Sie Fragen haben.
Riemannx unterstützt das Senden von grundlegenden Metriken. Sie können ein benutzerdefiniertes Modul erstellen, um jede Infrastruktur (Graphit, Zustrom usw.) zu unterstützen. Derzeit gibt es 3 Rückrufe:
udp_message_sent(size) - informiert, wann eine UDP -Nachricht gesendet wird und die Größe der Nachricht angibt.tcp_message_sent(size) - informiert, wann eine TCP -Nachricht gesendet wird und die Größe der Nachricht angibt.tls_message_sent(size) - informiert, wann eine TLS -Nachricht gesendet wird und die Größe der Nachricht angibt. Beiträge werden herzlich empfangen, finden Sie im Abschnitt "Projekte" für einige Ideen, die ich aufgeschrieben habe, und für die neuesten, was im Gange ist.
Dieses Repository verwendet den Gitflow -Workflow, was bedeutet, dass alle PRs auf den Entwicklungszweig hingewiesen werden sollten! . Im Folgenden finden Sie einige Dinge, die Sie berücksichtigen sollten, bevor Sie eine PR erstellen:
Ich möchte die Testabdeckung bei 100%beibehalten! - Ich kann diese Folie in dringenden Fällen (Fehler usw.) lassen
Um zu vermeiden, dass Travis unnötig überlastet wird, wäre dies geschätzt, wenn Sie zuerst die folgenden vor Ort überprüfen:
mix coveralls.html (Ziel für 100%)mix dialyzer (dauert eine Weile und ich schätze, Sie können nicht alle Erlang/Elixir -Versionen testen)Ich betrachte diese Client-Funktion vollständig, wenn Ihre PR die Kompatibilität rückwärts vollständig bricht oder das vorbestehende Verhalten/die Standardeinstellungen ändert.
Ein Teil des Code wurde vom ursprünglichen Elixir-Riemann-Client ausgeliehen. Der größte Teil des Protobufs kommt von dort aus.