Question

La carte réseau log4j envoie des événements sous forme d'objet Java sérialisé.J'aimerais pouvoir capturer cet objet et le désérialiser dans un langage différent (python).Est-ce possible?

NOTE La capture du réseau est simple ;c'est juste un socket TCP et une lecture dans un flux.La difficulté est la partie désérialisation

Était-ce utile?

La solution

En général, non.

Le format de flux pour la sérialisation Java est défini dans ce document, mais vous devez accéder aux définitions de classe d'origine (et à un environnement d'exécution Java dans lequel les charger) pour transformer les données de flux en quelque chose qui se rapproche des objets d'origine.Par exemple, les classes peuvent définir les méthodes writeObject() et readObject() pour personnaliser leur propre formulaire sérialisé.

(modifier: Lubos Hasko suggère d'avoir un petit programme Java pour désérialiser les objets devant Python, mais le problème est que pour que cela fonctionne, votre "petit programme Java" doit charger les mêmes versions de toutes les mêmes classes qu'il pourrait désérialiser.Ce qui est délicat si vous recevez des messages de journal d'une seule application, et vraiment délicat si vous multiplexez plusieurs flux de journaux.Quoi qu’il en soit, ce ne sera plus un petit programme. edit2 : Je peux me tromper ici, je ne sais pas ce qui est sérialisé.S'il ne s'agit que de classes log4j, ça devrait aller.D'un autre côté, il est possible de consigner des exceptions arbitraires, et si elles sont également placées dans le flux, mon argument est valable.)

Il serait beaucoup plus facile de personnaliser la carte réseau log4j et de remplacer la sérialisation brute par une forme plus facilement désérialisée (par exemple, vous pourriez utiliser XStream pour transformer l'objet en une représentation XML)

Autres conseils

Théoriquement, c'est possible.La sérialisation Java, comme à peu près tout dans Javaland, est standardisée.Alors, tu pourrait implémentez un désérialiseur selon cette norme en Python.Cependant, le format de sérialisation Java n'est pas conçu pour une utilisation multilingue ; le format de sérialisation est étroitement lié à la manière dont les objets sont représentés dans la JVM.Même si implémenter une JVM en Python est sûrement un exercice amusant, ce n'est probablement pas ce que vous recherchez (- :

Il existe d'autres formats de sérialisation (de données) spécialement conçus pour être indépendants du langage.Ils fonctionnent généralement en réduisant les formats de données au strict minimum (nombre, chaîne, séquence, dictionnaire et c'est tout) et nécessitent ainsi un peu de travail des deux côtés pour représenter un objet riche sous la forme d'un graphique de structures de données stupides (et vice-versa). versa).

Deux exemples sont JSON (notation d'objet JavaScript) et YAML (YAML n'est pas un langage de balisage).

ASN.1 (Notation de syntaxe abstraite 1) est un autre format de sérialisation des données.Au lieu de réduire le format au point où il peut être facilement compris, l'ASN.1 est auto-descriptif, ce qui signifie que toutes les informations nécessaires au décodage d'un flux sont codées dans le flux lui-même.

Et bien sûr, XML (langage de balisage extensible), fonctionnera également, à condition qu'il ne soit pas simplement utilisé pour fournir une représentation textuelle d'un "vidage de mémoire" d'un objet Java, mais un véritable codage abstrait et indépendant du langage.

Alors, pour faire court :votre meilleur pari est d'essayer de contraindre log4j à se connecter dans l'un des formats mentionnés ci-dessus, de remplacer log4j par quelque chose qui fait cela ou d'essayer d'intercepter les objets avant qu'ils ne soient envoyés sur le réseau et de les convertir avant de quitter Javaland.

Les bibliothèques qui implémentent JSON, YAML, ASN.1 et XML sont disponibles pour Java et Python (et pour presque tous les langages de programmation connus de l'homme).

Je recommanderais de passer à un format tiers (en créant vos propres adaptateurs log4j, etc.) que les deux langages comprennent et peuvent facilement marshaler/démarshaler, par ex.XML.

En théorie, c'est possible.La difficulté en pratique dépend désormais du fait que le format de sérialisation Java soit documenté ou non.Je suppose que ce n'est pas le cas. modifier: oups, j'avais tort, merci Charles.

Quoi qu'il en soit, c'est ce que je vous suggère de faire

  1. capturez à partir de log4j et désérialisez l'objet Java dans votre propre petit programme Java.

  2. maintenant, lorsque vous avez à nouveau l'objet, sérialisez-le à l'aide de votre propre formateur personnalisé.

    Conseil: Peut-être que vous n'avez même pas besoin d'écrire votre propre formateur personnalisé.Par exemple, JSON (faites défiler vers le bas pour les bibliothèques) possède des bibliothèques pour Python et Java, vous pouvez donc en théorie utiliser la bibliothèque Java pour sérialiser vos objets et la bibliothèque équivalente Python pour le désérialiser

  3. envoyer le flux de sortie à votre application python et le désérialiser

Charles a écrit :

Le problème est que pour que cela fonctionne, votre «petit programme Java» doit charger les mêmes versions de toutes les mêmes classes qu'il pourrait désérialiser.Ce qui est délicat si vous recevez des messages de journal d'une application, et vraiment délicat si vous multipliez plus d'un flux de journal.Quoi qu'il en soit, ce ne sera plus un petit programme.

Ne pouvez-vous pas simplement référencer les bibliothèques Java log4j dans votre propre processus Java ?Je donne ici simplement des conseils généraux qui s'appliquent à n'importe quelle paire de langues (le nom de la question est assez indépendant de la langue, je viens donc de fournir l'une des solutions génériques).Quoi qu'il en soit, je ne connais pas log4j et je ne sais pas si vous pouvez y "injecter" votre propre sérialiseur.Si vous le pouvez, votre suggestion est bien sûr bien meilleure et plus propre.

Eh bien, je ne suis pas un expert en Python, je ne peux donc pas commenter la façon de résoudre votre problème, mais si vous avez un programme en .NET, vous pouvez utiliser IKVM.NET pour désérialiser facilement les objets Java.J'ai expérimenté cela en créant un client .NET pour les messages de journal Log4J écrits dans Socket Appender et cela a très bien fonctionné.

Je suis désolé si cette réponse n'a pas de sens ici.

Si vous pouvez avoir une JVM du côté réception et les définitions de classe pour les données sérialisées, et que vous souhaitez utiliser uniquement Python et aucun autre langage, vous pouvez utiliser Jython :

  • vous désérialiseriez ce que vous avez reçu en utilisant les méthodes Java correctes
  • puis vous traitez ce que vous obtenez avec votre code Python
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top