문제

log4j 네트워크 어댑터는 이벤트를 직렬화 된 Java 객체로 보냅니다.이 개체를 캡처하고 다른 언어 (python)로 역 직렬화 할 수 있기를 바랍니다.가능합니까?

참고 네트워크 캡처는 쉽습니다.그것은 단지 TCP 소켓이고 스트림에서 읽는 것입니다.어려움은 역 직렬화 부분입니다

도움이 되었습니까?

해결책

일반적으로 아닙니다.

Java 직렬화를위한 스트림 형식은 이 문서에서 정의됩니다. a> 그러나 스트림 데이터를 원래 객체에 접근하는 것으로 되돌리려면 원래 클래스 정의 (및이를로드 할 Java 런타임)에 액세스해야합니다. 예를 들어 클래스는 writeObject () 및 readObject () 메서드를 정의하여 직렬화 된 형식을 사용자 지정할 수 있습니다.

( edit : lubos hasko는 Python 앞에서 객체를 역 직렬화하는 작은 자바 프로그램이 있다고 제안하지만 문제는 이것이 작동하려면 "작은 자바 프로그램"이 역 직렬화 할 수있는 모든 동일한 클래스의 동일한 버전입니다. 한 앱에서 로그 메시지를 수신하는 경우 까다 롭고 둘 이상의 로그 스트림을 멀티플렉싱하는 경우 정말 까다 롭습니다. 어느 쪽이든 조금은되지 않을 것입니다. edit2 : 여기서 틀렸을 수 있습니다. 무엇이 직렬화되는지 모르겠습니다. log4j 클래스 만 있으면 괜찮습니다. 반면에 임의의 예외를 기록 할 수 있습니다. 그리고 그들이 스트림에 들어가면 내 요점이 있습니다.)

log4j 네트워크 어댑터를 사용자 정의하고 원시 직렬화를 좀 더 쉽게 역 직렬화 한 형식으로 대체하는 것이 훨씬 쉬울 것입니다 (예를 들어 XStream을 사용하여 객체를 XML 표현으로 바꿀 수 있음)

다른 팁

이론적으로 가능합니다. Javaland의 거의 모든 것과 마찬가지로 Java Serialization은 표준화되어 있습니다. 따라서 Python의 해당 표준에 따라 deserializer를 구현 할 수 있습니다 . 그러나 Java 직렬화 형식은 언어 간 사용을 위해 설계되지 않았으며 직렬화 형식은 JVM 내부에서 객체가 표현되는 방식과 밀접하게 연결되어 있습니다. 파이썬에서 JVM을 구현하는 것은 확실히 재미있는 연습이지만, 아마도 당신이 찾고있는 것이 아닐 것입니다 (-:

언어에 구애받지 않도록 특별히 설계된 다른 (데이터) 직렬화 형식이 있습니다. 그들은 일반적으로 데이터 형식을 최소한 (숫자, 문자열, 시퀀스, 사전 및 그게 다)까지 제거하여 작업하므로 풍부한 개체를 멍청한 데이터 구조의 그래프로 표현하기 위해 양쪽 끝에 약간의 작업이 필요합니다 (그 반대도 마찬가지입니다). 마찬가지로).

두 가지 예는 JSON (JavaScript Object Notation) YAML (YAML Ai n't Markup Language) .

ASN.1 (Abstract Syntax Notation 하나) 는 다른 데이터 직렬화 형식입니다. ASN.1은 쉽게 이해할 수있는 지점까지 형식을 멍청하게 만드는 대신, 스트림을 디코딩하는 데 필요한 모든 정보가 스트림 자체 내에서 인코딩됨을 의미합니다.

물론 XML (eXtensible Markup Language) 는 Java 객체의 "메모리 덤프"의 텍스트 표현을 제공하는 데 사용되는 것이 아니라 실제 추상, 언어에 구애받지 않는 인코딩을 제공하는 경우에도 작동합니다.

그래서 짧게 말하면 가장 좋은 방법은 log4j를 위에서 언급 한 형식 중 하나로 로그인하도록 강제하거나 log4j를 그렇게하는 것으로 바꾸거나 객체가 존재하기 전에 가로 채려고하는 것입니다. 유선으로 전송하고 자바 랜드를 떠나기 전에 변환합니다.

JSON, YAML, ASN.1 및 XML을 구현하는 라이브러리는 Java와 Python (그리고 사람에게 알려진 거의 모든 프로그래밍 언어)에서 사용할 수 있습니다.

두 언어가 이해하고 쉽게 마샬링 / 마샬링 할 수있는 타사 형식 (자신의 log4j 어댑터 등을 만들어서)으로 이동하는 것이 좋습니다.XML.

이론적으로 가능합니다. 이제 실제로 얼마나 어려울지는 Java 직렬화 형식이 문서화되었는지 여부에 달려 있습니다. 아니에요. 수정 : 죄송합니다. 제가 틀 렸습니다. 감사합니다. 찰스 .

어쨌든 이것이 제가 권장하는 작업입니다.

  1. log4j에서 캡처하고 자신의 작은 Java 프로그램에서 Java 개체를 역 직렬화합니다.

  2. 이제 개체를 다시 가져 오면 사용자 지정 포맷터를 사용하여 직렬화합니다.

    팁 : 사용자 지정 포맷터를 작성할 필요가 없을 수도 있습니다. 예를 들어 JSON (libs의 경우 아래로 스크롤) 에는 Python 및 Java 용 라이브러리가 있으므로 이론적으로 사용할 수 있습니다. 객체를 직렬화하는 Java 라이브러리와 역 직렬화하는 Python 동등한 라이브러리

  3. 출력 스트림을 Python 애플리케이션으로 보내고 역 직렬화 <인용구>

    Charles는 다음과 같이 썼습니다.

    문제는 작동하려면 "작은 자바 프로그램" 모두 동일한 버전을로드해야합니다. 같은 클래스 deserialize. 만약 당신이 하나의 앱에서 로그 메시지 수신, 그리고 만약 당신이 둘 이상의 로그 스트림을 다중화합니다. 어느 쪽이든, 그것은 더 이상 작은 프로그램.

    자신의 자바 프로세스에서 단순히 자바 log4j 라이브러리를 참조하면 안 되나요? 나는 여기에서 모든 언어 쌍에 적용 가능한 일반적인 조언을 제공하고 있습니다 (질문의 이름은 언어에 구애받지 않으므로 일반적인 솔루션 중 하나를 제공했습니다). 어쨌든, 나는 log4j에 익숙하지 않으며 자신의 serializer를 그것에 "주입"할 수 있는지 여부를 모릅니다. 가능하다면 당연히 귀하의 제안이 훨씬 더 좋고 깨끗합니다.

저는 Python 전문가가 아니므로 문제 해결 방법에 대해서는 언급 할 수 없지만 .NET에 프로그램이있는 경우 IKVM.NET을 사용하여 Java 개체를 쉽게 deserialize 할 수 있습니다.나는 소켓 어 펜더에 기록 된 Log4J 로그 메시지를위한 .NET 클라이언트를 생성하여 이것을 실험 해 보았고 정말 잘 작동했습니다.

이 답변이 의미가없는 경우 죄송합니다.

수신 측에 JVM이 있고 직렬화 된 데이터에 대한 클래스 정의가 있고 Python 만 사용하고 다른 언어는 사용하지 않으려면 Jython을 사용할 수 있습니다.

  • 올바른 Java 메소드를 사용하여받은 것을 역 직렬화합니다.
  • 그런 다음 Python 코드로 얻은 것을 처리합니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top