Dans le processus de création d'un système qui utilise fluentd, je me demandais comment tester que les données avaient été envoyées à fluentd en premier lieu, j'ai donc étudié diverses choses.
Dans le processus de création d'un système qui utilise fluentd, je souhaite écrire un test rapide pour confirmer que les données sont envoyées à fluentd.
Je veux raccourcir le temps de test autant que possible lors de l'exécution de CI, donc je veux lier les données générées par FluentLogger pour les sortir en temps réel autant que possible.
J'avais l'habitude d'écrire le code pour ouvrir la socket et attendre par moi-même, mais depuis que la version a augmenté et que SSL est devenu impliqué, cela est devenu gênant, alors j'aimerais faire quelque chose avec le plugin autant que possible.
Comme j'utilise souvent docker pour configurer le middleware environnant lors de la conversion de CI, j'ai essayé de mettre Elasticsearch dans le kit de middleware une fois auparavant, mais j'ai volontairement construit Elasticsearch que je n'ai pas appelé directement et elasticsearch-ruby pour le test C'est aussi paresseux de le mettre et de le connecter. .. .. Surtout avec l'image officielle, cela ne se produit pas avec un seul nœud, et il est difficile de suivre et de mettre à jour avec tous les micro-services lorsque la version change, donc je voudrais tester sans middleware supplémentaire autant que possible.
La mise en mémoire tampon fluentd est toujours effectuée en ajustant la valeur de flush_interval
, mais s'il s'agit d'un test, il semble que vous puissiez utiliser flush_mode = immédiat
Cette fois, quand j'ai réfléchi à la façon de faire bon usage de Redis, qui est également utilisé dans ActiveJob etc., il y avait un bon plug-in dans la Official plug-in list, alors je l'ai essayé. Essayer.
Il y avait aussi MySQL, mais la structure des données envoyées depuis FluentLogger est assez différente, donc le plug-in redis qui le met en place était plus approprié.
Nous procéderons à l'installation Gem et aux réglages fluides nécessaires en fonction de l'étude de la méthode.
Quant à gem, il suffit qu'il y ait un plug fluent-plugin-redis-store en plus du corps principal, donc je vais tout mettre ensemble
command
gem install fluentd fluent-plugin-redis-store --no-document
J'omettrai l'installation de Redis, mais construirai redis en utilisant brew ou docker.
Puisque fluentd est reçu de forward et envoyé à redis_store, fluent.conf ressemble à ceci.
fluent.conf
<source>
@type forward
@id input1
@label @mainstream
port 24224
</source>
<label @mainstream>
<filter **>
@type record_transformer
<record>
tag ${tag}
</record>
</filter>
<match **>
@type copy
<store>
@type stdout
</store>
<store>
@type redis_store
key_path tag
<buffer>
flush_mode immediate
</buffer>
</store>
</match>
</label>
Ce que je fais est comme ça.
@ mainstream
@ mainstream
comme filtre@ mainstream
comme correspondance avec stdout et redis_storeflush_mode immédiat
C'est un bonus de le mettre sur stdout, mais si vous le sortez, il est facile de le débuck plus tard.
Écrivez ceci dans . / Fluent.conf
et lancez fluentd
fluentd -c fluent.conf
Maintenant que je suis prêt, j'aimerais ajouter les données, mais il est plus facile de comprendre le mouvement si vous surveillez Redis, alors ouvrez une autre fenêtre et surveillez-la.
redis-cli monitor
Où envoyer des données à fluentd, l'application actuelle utilise fluent-logger-ruby pour envoyer des données, mais cette fois `fluent-cat Essayez d'utiliser ʻ comme substitut
echo '{ "key" : "sample" }' | bundle exe fluent-cat debug.test
Il s'agit d'une commande qui envoie les données avec la balise debug.test
et l'horodatage de l'heure actuelle aux données {" key ":" sample "}
. S'il n'est pas défini, il sera adressé à localhost, de sorte que les données seront envoyées au serveur fluentd construit ci-dessus.
Ensuite, la sortie suivante sera sortie vers la sortie standard du côté fluent.
fenêtre d'exécution fluide
2020-11-03 09:37:28.016591000 +0900 debug.test: {"key":"sample","tag":"debug.test"}
Ceci est généré par @type stdout
défini dans fluent.conf
, et il peut être confirmé que le filtre a une balise ajoutée après avoir effectivement reçu les données.
De plus, en regardant la fenêtre de surveillance Redis, elle s'affiche comme suit.
redis-fenêtre d'exécution cli
1604363848.025602 [0 172.28.0.1:40998] "zadd" "debug.test" "1604363848.016591" "{\"key\":\"sample\",\"tag\":\"debug.test\"}"
Il est ajouté comme décrit dans le readme du plugin. Le paramétrage de «key_path tag» est effectif pour key, et «debug.test», qui est la valeur du tag inclus dans les données, est défini.
Essayez d'obtenir les données de Redis.
redis-cli zrange debug.test 0 -1 withscores
1) "{\"key\":\"sample\",\"tag\":\"debug.test\"}"
2) "1604363848.016591"
Étant donné que l'horodatage est un score, il est trié pour que vous puissiez en mettre beaucoup.
Au fait, le rubis est comme ça.
require 'redis'
Redis.new.zrange 'debug.test', 0, -1, withscores: true
output
=> [["{\"key\":\"sample\",\"tag\":\"debug.test\"}", 1604363848.016591]]
Pour le moment, la valeur peut être prise simplement, il semble donc relativement facile à utiliser.
Lors de l'exécution de tests en parallèle à l'aide de «parallel_tests» ou de «test-queue», il devient nécessaire de déterminer quel processus de test est entré dans le journal. À ce moment-là, vous pouvez inclure l'ID de processus dans les données à envoyer et l'utiliser pour définir la clé.
Je veux mettre l'ID de processus, l'heure et l'ID de demande dans le fichier journal Rails, donc je ne pense pas que cela causera un dommage.
Dans ce cas, les données à envoyer seront les suivantes
{ "key" : "sample", "pid" : 123 }
Parallèlement à cela, changez fluent.conf
comme suit.
<label @mainstream>
<filter **>
@type record_transformer
<record>
tag ${tag}
+ tag_with_pid '${tag}.${record["pid"]}'
</record>
</filter>
<match **>
@type copy
<store>
@type stdout
</store>
<store>
@type redis_store
- key_path tag
+ key_path tag_with_pid
<buffer>
flush_mode immediate
</buffer>
</store>
</match>
</label>
Maintenant que l'ID de processus est entré dans la clé lors de son enregistrement dans Redis, utilisez cet ID de processus pour identifier le journal de votre propre processus et évaluez-le pour déterminer si les données ont été réellement envoyées. Vous pourrez.
Il semble que vous puissiez modifier le paramètre sous la forme suivante comme décrit dans README
<label @mainstream>
<filter **>
@type record_transformer
<record>
tag ${tag}
</record>
</filter>
<match **>
@type copy
<store>
@type stdout
</store>
<store>
@type redis_store
key_path tag
+ host 10.0.0.1
+ db 11
<buffer>
flush_mode immediate
</buffer>
</store>
</match>
</label>
Lorsque vous l'utilisez dans un test, si vous créez un assistant comme celui-ci, il sera facile à utiliser
# frozen_string_literal: true
require 'redis'
module FluentdLogHelper
def fetch_fluentd_log_by(tag:, pid: nil)
redis_key = pid ? "#{tag}.#{pid}" : tag
redis.zrange redis_key, 0, -1
end
def redis(options = {})
options[:db] ||= 0
@redis ||= Redis.new(options)
end
end
Nom simple
fetch_fluentd_log_by tag: 'debug.test'
Appeler avec l'identifiant de processus
fetch_fluentd_log_by tag: 'debug.test', pid: Process.pid
Recommended Posts