Un client Riemann entièrement en vedette construit sur la fiabilité de Poolboy et la puissance impressionnante d'Elixir!
Riemannx est un client Riemann construit dans Elixir, actuellement c'est le seul client d'Elixir qui prend en charge UDP et TLS (ainsi que TCP). Il existe également un mode de lots que vous pouvez utiliser qui fonctionne avec l'un des transports.
Il a une option combinée expérimentale qui tire le meilleur parti de TCP et UDP - en mode combiné, UDP est l'approche privilégiée, mais si la taille du message dépasse le jeu de taille UDP maximum que TCP sera utilisé.
Comme toujours, les conditions préalables sont requises avant d'utiliser Riemannx, la plupart d'entre elles sont évidentes (Elixir, Erlang) mais contiennent des informations sur les versions testées et prises en charge.
Actuellement, toutes les versions Erlang ~> 18 sont prises en charge. Cela comprend 20, 20,1 n'est pas encore testé mais je ne prévois aucun problème là-bas.
Testé par Travis:
18.019.320.0J'ai essayé d'assurer la compatibilité à partir de 1.3.4 et je continuerai de le faire, le cas échéant. Combinaisons testées:
18.0 Elixir: 1.3.4 / 1.4.5 / 1.5.119.3 Elixir: 1.3.4 / 1.4.5 / 1.5.120.0 Elixir: 1.4.5 / 1.5.1Comme c'est souvent le cas, un client est assez inutile sans son homologue de serveur - pour plus d'informations sur Riemann, visitez http://riemann.io.
Le client n'a été testé que sur la bataille: 0.2.11 . À partir de la version 4.0.0 du client, vous devrez définir use_micro sur FAUX si vous utilisez une version de Riemann plus âgée que 0.2.13 et ne définissez pas le champ d'heure vous-même. Cela devrait fonctionner avec 0.3.0 mais encore une fois n'a pas été testé auparavant (quiconque souhaite travailler sur des tests d'intégration, je l'apprécierais grandement).
L'installation se produit comme n'importe quelle autre bibliothèque Elixir, ajoutez-la à votre fichier de mixage et le reste est historique:
def deps do
[ { :riemannx , "~> 4.0" } ]
endAssurez-vous d'ajouter Riemannx à la liste des applications dans votre fichier mix.exs, cela garantit qu'il est démarré avec votre application et qu'il sera inclus dans vos versions (si vous utilisez un gestionnaire de version):
applications : [ :logger , :riemannx ] Pour utiliser Riemannx, tout ce que vous avez à faire est de remplir certaines entrées de configuration - après cela, tout se passe automatiquement (sauf pour l'envoi réel bien sûr). Vous trouverez ci-dessous une liste complète des options disponibles:
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 prend en charge deux méthodes send , l'une asynchrone l'autre synchrone:
L'envoi synchrone vous permet de gérer les erreurs qui pourraient se produire lors de l'envoi, ci-dessous est un exemple montrant à la fois à quoi ressemble cette erreur et ce qui se passe lors d'un envoi réussi:
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 } " )
endL'envoi asynchrone est beaucoup plus rapide, mais vous ne savez jamais vraiment si votre message l'a fait, dans de nombreux cas, ce type d'envoi est suffisamment sûr et pour la plupart des cas d'utilisation, le choix recommandé. C'est assez simple à mettre en œuvre:
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!Remarque: Si un travailleur n'est pas en mesure de l'envoyer mourra et sera redémarré, ce qui lui donne une chance de revenir à un état «correct». Sur un envoi asynchrone, cela se fait par correspondance de modèle: OK avec la commande Send, pour les envois synchrones si la valeur de retour est une erreur, nous tuons le travailleur avant de retourner le résultat.
Le support TLS vous permet d'utiliser une connexion TCP sécurisée avec votre serveur Riemann, pour en savoir plus sur la façon de configurer ce
Si vous choisissez d'utiliser TLS, vous utiliserez une configuration purement TCP, combinée n'est pas prise en charge (et ne devrait pas être non plus) avec TLS:
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
]
]En supposant que vous avez correctement configuré le côté serveur, cela devrait être tout ce dont vous avez besoin pour commencer.
Riemann a le concept d'un index interrogable qui vous permet de rechercher des événements spécifiques, les index doivent être spécialement créés dans votre configuration, sinon le serveur renverra une erreur "sans index".
# 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: _}]Pour plus d'informations sur la requête et les fonctionnalités linguistiques ont un aperçu des concepts de base.
Cette section contient quelques notes sur le comportement de Riemannx qui peuvent vous intéresser ou répondre aux questions que vous avez sur certaines choses.
Lot à partir de 4.0.0 est le comportement de connexion par défaut - la taille par défaut du lot est de 50 et l'intervalle est toutes les 1 seconde. Le lot fonctionne comme tel:
Tout ce qui est dans la file d'attente sera envoyé chaque intervalle.
Si la taille de la file d'attente atteint la taille du lot de set, elle sera rincée quel que soit l'intervalle.
Les lots seront supprimés si aucun travailleur n'est disponible pour gérer le lot à moins que checkout_timer ne soit défini sur :infinity
Il y a un nouveau type appelé :batch et une clé de paramètres appelée batch_settings: dans Batch_settings, vous pouvez spécifier un type pour la connexion sous-jacente ( :tcp , :udp , :combined , :tls ). Comme toujours combiné est la valeur par défaut.
Éventuellement, un numéro de limite par lots peut être spécifié ( :limit ). S'il est défini, une fois que la file d'attente par lots a la quantité spécifiée de lots, c'est-à-dire des événements limit * batch_size , de nouveaux événements seront supprimés jusqu'à ce qu'au moins un lot soit envoyé. La valeur par défaut est :infinity
À partir de la version 0.2.13 de Riemann, il a été possible de définir du temps en microsecondes - Riemannx prend maintenant en charge et utilise le champ time_micros (sauf si vous avez réglé le champ Time ou Time_micros vous-même, Riemannx ne l'écrasera pas). Si vous utilisez une ancienne version de Riemann, elle n'utilisera que le champ de secondes.
Remarque: si vous définissez le temps et le temps_micros, Riemann prioritra le micro-temps et Riemannx se remplacera ni l'un ni l'autre.
Cela semble plus sophistiqué qu'il ne l'est mais décrit essentiellement la fonctionnalité qui ajoute une entrée d'hôte à votre événement si vous n'en avez pas spécifié. Il existe 3 façons de spécifier un hôte:
Faites-le avant d'envoyer l'événement (ajoutez une touche hôte à la liste des mots clés)
Ajoutez la touche :event_host à votre configuration.
Laissez Riemannx le faire en utilisant :inet.gethostname() - Nous n'appelons cela qu'une seule fois et enregistrons le résultat, il n'est pas appelé à chaque événement.
Les 2 dernières options sont les plus favorables car elles garderont votre code propre.
Dans ce client, il y a la possibilité de fixer une priorité pour vos travailleurs vous permettant de accorder une priorité plus élevée ou moins sur l'envoi de vos statistiques à Riemann.
La différence définir une priorité dépend fortement du matériel et de la façon dont vous avez défini vos autres priorités en général, plus d'informations peuvent être trouvées ici: http://erlang.org/doc/man/erlang.html#process_flag-20
Si vous essayez de définir la priorité sur: Max Riemannx augmentera une éERROR RUNIMEAD car c'est une idée terrible. Il augmentera également un runTimeError si vous essayez: FOO parce que c'est aussi une idée terrible.
La migration vers 3.0 est essentiellement juste un cas de modification de votre disposition de configuration - toutes les mêmes options existent, sauf que maintenant vous avez plus de contrôle sur vos travailleurs au niveau de type, cela est particulièrement précieux lorsque vous utilisez la configuration combinée comme vous le pouviez, disons, avoir un plus petit pool de travailleurs TCP et un plus grand pool de travailleurs UDP plutôt que avant (2x quel que soit le pool_size que vous avez donné).
Vous pouvez voir cette nouvelle mise en page ici: config
Si quelque chose n'a pas de sens ici, n'hésitez pas à ouvrir un problème afin que nous puissions étendre le ReadMe pour réparer l'ildoucité.
Si vous souhaitez stocker vos paramètres ailleurs, vous pouvez créer un backend pour lire les paramètres à partir d'une base de données par exemple. Regardez le module Paramètres par défaut pour les rappels requis.
Cela peut être utile si vous souhaitez stocker des paramètres à l'échelle de l'entreprise en un seul endroit.
N'hésitez pas à ouvrir un problème si vous avez des questions.
Riemannx prend en charge l'envoi de mesures de base, vous pouvez créer un module personnalisé pour prendre en charge toute infrastructure (graphite, afflux etc.). Il y a actuellement 3 rappels:
udp_message_sent(size) - Informe lorsqu'un message UDP est envoyé et donne la taille du message.tcp_message_sent(size) - Informe lorsqu'un message TCP est envoyé et donne la taille du message.tls_message_sent(size) - Informe lorsqu'un message TLS est envoyé et donne la taille du message. Les contributions sont chaleureusement reçues, consultez la section Projets pour certaines idées que j'ai écrites et pour les dernières personnes sur ce qui est en cours.
Ce référentiel utilise le flux de travail Gitflow qui signifie que tous les relations publiques doivent être pointés vers la branche de développement! . Vous trouverez ci-dessous certaines choses à considérer avant de créer un RP:
Je voudrais maintenir la couverture des tests à 100%! - Je peux laisser cette diapositive dans des cas urgents (bogues etc.)
Pour éviter la congestion de Travis inutilement, il serait apprécié si vous vérifiez d'abord le suivant localement:
mix coveralls.html (viser 100%)mix dialyzer (prend un certain temps et j'apprécie que vous ne puissiez pas tester toutes les versions Erlang / Elixir)Je considère que cette fonctionnalité du client est terminée, si votre PR casse complètement la compatibilité en arrière ou modifie les comportements / valeurs par défaut préexistants que j'apprécierais une tête et vos justifications :).
Une partie du code a été empruntée au client Elixir-Riemann d'origine. La plupart des trucs Protobuf viennent de là.