Repository navigation
v0.10.0
Ajouté
-
Découpage #111 : RsysLogstach devient le connecteur rsyslog, la sémantique
Logstash part dans PyStashTemplate (v0.1.0).
src/ne garde que le connecteur :omprog,indexer,dlq,metrics,
opensearchconf(+ soni18nde domainersyslogstach) ; les modules
templates,filters,interpreter,enrichment,grok,fingerprint,
useragent,xmlfilter,multievents,dnslookup,simples,util,
tracinget leurs tests vivent désormais dans le paquet
pystashtemplate(dépendance git figée sur le tagv0.1.0), comme tout
autre outil (…beat) pourrait le faire. Variables d'environnement :
PYSTASHTEMPLATE_LOCALEDIR/PYSTASHTEMPLATE_DNS(anciens noms
RSYSLOGSTACH_*lus en repli). Suivi détaillé sur l'issue #111. -
CI et publication : repli GitHub autorisé, publication manuelle sur un tag
déjà livré dans main, vérification d’ascendance et archives du tag exact.
Tests
- Couverture étendue à
scripts/(#154, suite de #73) :source = ["src", "scripts"], tests decheck_branch_protection.py(0 % → 100 %) et des points d'entrée des trois scripts. Seuil inchangé à 95 %.
Corrigé
- Chaînes des
.conf(#128) : les antislashs entre guillemets sont conservés, comme Logstash (config.support_escapes: false) —"a\.b"vauta\.bet"\d+"vaut\d+, au lieu d'être retirés parlogstash-pipeline-parser. Les regex degsubet des conditions=~ "..."redeviennent fidèles ; prérequis des motifsgrok(#112). - Gabarits (#102) :
%{+%s}rend les secondes depuis l'epoch de@timestamp, comme Logstash, au lieu de%0.
Modifié
- Indexer délégué aux sorties PyStashTemplate (#160) :
OpenSearchIndexergarde sa signature et son contrat (SendOutcome, DLQ, fingerprint, gabarit) mais envoie viaOpenSearchOutput(issue #12, API_bulk, un document par lot — accusé réel,retry_max=0parité) ;dlq.pydevient un ré-export du portpystashtemplate.dlq(format identique) ;install_index_templatepasse par le client httpx de la sortie. Dépendance PyStashTemplate épinglée àv0.2.0,opensearch-pyretirée. Changements documentés : le failover multi-nœuds du transport opensearch-py disparaît (premier nœud seul, avertissement si plusieurs — l'échec rend le message à rsyslog, qui le retient) ;pipelineest désormais transmis aussi pourupdate/delete(l'ancien client l'ignorait silencieusement) ;PipelineInterpreter.apply_eventsdoit être attendu (PyStashTemplate #34). - Licence (#91) : passage de MIT à GPL-3.0-or-later.
LICENSEcontient désormais le texte officiel de la GPLv3 ; s'y ajoutentlicensedanspyproject.toml, les en-têtes SPDX, la section Licence du README avec les licences des dépendances, ettests/test_licence.py.
Ajouté
- Variables d'environnement du
.conf(#122) :${VAR}et${VAR:défaut}substitués au chargement, avant l'analyse — comme Logstash. La variable définie prime sur la valeur par défaut ; une variable non définie sans défaut refuse le démarrage (ValueErrorqui la nomme).%{champ}(rendu par événement) et les noms invalides (${1x}) ne sont pas touchés. Les exemplespipeline.example.d/gagnent des valeurs par défaut. cloneetsplitnatifs (#141) : un message peut produire plusieurs événements.clone(clones,typeou tag selonecs_compatibility) etsplit(field,terminator,target, tag_splitparsefailure) ; les nouveaux événements poursuivent le pipeline après le filtre et omprog indexe chacun selon ses sorties. Nouvelle méthodePipelineInterpreter.apply_events;applyne renvoie que les actions du document d'origine. Toutes les sectionsfilter{}passent désormais avant les sectionsoutput{}, comme Logstash.- Sorties
opensearch(#126) :action(index,create,update,
delete),pipeline,routingetdoc_as_upsert, en gabarits sprintf. --field-reference-escape-style(#124) : crochets échappés (percent,
ampersand) dans les noms de champs, commefield_reference.escape_style.- Connexion OpenSearch dans le
.conf(#125) :hosts,user,password,ssl,ssl_certificate_verification,cacert,tls_certificateettls_keysont lus dans les blocsopensearch{}/elasticsearch{}deoutput{}, branches comprises. Sans schéma, une URL dehostsest enhttpsaufssl => true(défaut Logstash). La ligne de commande etOPENSEARCH_USER/OPENSEARCH_PASSWORDrestent prioritaires ; des valeurs différentes d'un bloc à l'autre,sslcontraire au schéma ou une variable${VAR}non remplacée bloquent le démarrage. - Gabarits de date (#123) : lettres Java Time manquantes dans
%{{…}}(G,u,Y,Q/q,MMM/MMMM,L,w,W,D,E,e,c,a,h,K,k,n,N,A,VV,O) et lettres Joda propres à%{+…}(C,x,e,E,MMM).S…affiche désormais les microsecondes (SSSSSS→123456au lieu de123000). dnsnatif (#121) dans les.conf:resolve,reverse,action(append/replace),hostsfile,nameserver(chaîne, liste ou hashaddress/search/ndots),timeout,max_retries,tag_on_timeout, caches des succès et des échecs avec durée de vie, noms IDNA.RSYSLOGSTACH_DNS=offcoupe les requêtes réseau.xmlnatif (#121) dans les.conf:store_xml(conversion façon XmlSimple, comme Logstash),xpathavecnamespacesetremove_namespaces,parse_options,force_array,force_content,suppress_empty, tag_xmlparsefailure. Entités externes, DTD et XInclude jamais actifs.useragentnatif (#121) dans les.conf: analyse ua-parser (motifs uap-core), champs ECS ([user_agent][name],[version],[device][name],[os][name|version|full], détail des versions dans[@metadata][filter][user_agent]) ou anciens champs avececs_compatibility => disabledetprefix, optionstarget,regexes,lru_cache_size.- Plugin
date: millisecondes, fuseaux textuels etlocale(#118) :SSS(via%f, qui met à l'échelle pareil : « 123 » → 123 ms), noms de fuseauxz/zz/zzz/ZZZ(« CET » → +01:00, IDs IANA « Europe/Paris » viaZoneInfo; abréviations réduites aux zones européennes et nord-américaines courantes) et optionlocale(fr: noms de mois/jours traduits vers l'anglais avantstrptime, sanssetlocaleglobal). Le fuseau textuel trouvé dans la valeur prime surtimezone, comme un fuseau explicite. translatecomplet (#119), dans les.confet le steptranslatede--filters(une seule implémentation,filters.TranslateFilter) :dictionaryen ligne, dictionnaires JSON et CSV en plus du YAML,exact,regex,override,iterate_on(tableau de valeurs ou d'objets),refresh_intervaletrefresh_behaviour(merge/replace), anciens nomsfield/destination,targetfacultatif (traduction en place). Comportement de logstash-filter-translate : untargetdéjà présent n'est plus réécrit sansoverride => true, et un champ source absent ne déclenche plus lefallback.- Plugins
filter{}simples natifs (#120) :csv,cidr,prune,urldecode,
uuid,syslog_pri,truncate(modulesimples.py). dissectnatif (#117) :convert_datatype(int,float) ettag_on_failure
(défaut_dissectfailure). Un échec de découpage est désormais tagué, comme
Logstash, au lieu d'être ignoré en silence.- Filtre
json { … }natif dans--pipeline-conf(#115) :source,target,
skip_on_invalid_json,tag_on_failure. - Filtre
fingerprint { … }natif dans--pipeline-conf(#114) : méthodes
SHA1/SHA256/SHA384/SHA512/MD5, HMAC, MURMUR3, UUID, IPV4_NETWORK,
base64encode,concatenate_sources,concatenate_all_fields. - Plugin
kven bloc natif (#113) :filter { kv { ... } }réutilisefilters.KeyValueFilter—source(défautmessage),target(fusion dans un hash existant, comme Logstash),field_split,value_split,include_keys,exclude_keys,prefix,trim_key,trim_value,allow_duplicate_values. Une clé répétée dans la source vaut la liste de ses valeurs (comportement du plugin officiel) ;allow_duplicate_values => falsedéduplique en gardant l'ordre. Le stepkvde--filtersgagne les mêmes options. Lignekvde l'audit #101 mise à jour. - Options communes sur tous les filtres (#116) :
add_field,add_tag,remove_field,remove_tags'appliquent après tout filtre natif réussi (dissect,date,geoip,translate,mmdb,kv,grok), plus seulement aprèsmutate, commefilter_matchedde Logstash ; jamais après un échec. Fonction partagéefilters.apply_common_options. grok {}natif dans un pipeline.conf(#112) : modulegrok.py, bibliothèque des 70 motifs de base de logstash-patterns-core (Apache-2.0, attribution dansLICENSES/),%{SYNTAXE:champ:int|float}, groupes nommés(?<champ>...), optionsbreak_on_match,overwrite,tag_on_failure,patterns_dir,patterns_files_glob,pattern_definitions,keep_empty_captures,target. Motifs compilés une fois par jeu d'options.- Audit des fonctions Logstash (#101) :
docs/audit-fonctions-logstash.md, tableau fonction / fait ou pas fait / commentaires (gabarits sprintf, conditions, pluginsfilter{}etoutput{}, options communes). - Authentification par certificat client (mTLS) (#100) :
--cacert,--tls-certificate,--tls-key, mêmes noms que le plugin logstash-output-opensearch, transmis au client opensearch-py. Refus au démarrage si certificat et clé ne vont pas ensemble, si les nœuds sont enhttp://ou si un fichier manque. Test de bout en bout contre un serveur HTTPS local qui exige un certificat client. - Métriques Prometheus (#35) : module
metrics.py(prometheus-client 0.26.0, registre propre au pont), endpoint/metricsactivé par--metrics-port(désactivé par défaut, écoute sur 127.0.0.1). Compteurs reçus/issues/erreurs, histogrammes de latence d'indexation et de taille, jauges de taille de DLQ et de renvois en attente. - Internationalisation (#38) : journaux
infoet au-dessus et aide de la ligne de commande traduisibles (gettext, domainersyslogstach, langue choisie par l'environnement), 29 langues listées danslang/LINGUAS(traduction anglaise complète, les autres à faire),scripts/i18n-update.sh(mise à jour,--check,--compile),scripts/i18n_report.py, job CI « i18n », workflowi18n.yml(PR de mise à jour des catalogues) ; les.mosont installés par la roue dansshare/locale. - Règles de protection versionnées
.github/branch-protection/{main,dev}.json(relevées sur la protection réelle du 22/10/2026), vérifiées par le workflowbranch-protection.yml(push sur main/dev, chaque jour) etscripts/check_branch_protection.py(socle Mathilde-Team/.github#1, #83). drop {}natif dans un pipeline.conf(#34) :if [x] == "bruit" { drop { } }écarte le document (apply()renvoieNone, comme un step"drop"defilters_json) ; optionpercentagehonorée comme dans Logstash.- Step
"date"dans--filters(#34) :match,target,timezone,tag_on_failure, comme le plugindatedes.conf. Les deux mécanismes partagent désormaisfilters.DateFilter(logique déplacée d'interpreter.py). Unmatchmal formé est refusé dès le chargement de--filters(ValueError), et reste ignoré dans un.conf. Makefile(#103, fin de #73) : cibles usuelles (test,lint,fmt,fmt-fix,i18n,seuil) exécutant les mêmes commandes que la CI ; le seuil de couverture y est lu depuispyproject.toml(tomllib), jamais recopié — une seule source de vérité. Section Tests du README mise à jour.