2016-11-15 90 views
2

我想在使用Camel Rest端點時記錄原始的'原始'請求正文(例如JSON)。什麼是正確的方法來做到這一點?如何在使用Camel Rest時記錄請求負載?

我的設置(RouteBuilder)看起來是這樣的:

restConfiguration().component("jetty") 
    .host(this.host) 
    .port(this.port) 
    .contextPath(this.contextPath) 
    .bindingMode(RestBindingMode.json); 

rest("myService/").post() 
    .produces("application/json; charset=UTF-8") 
    .type(MyServiceRequest.class) 
    .outType(MyServiceResponse.class) 
    .to(SERVICE_CONTEXT_IN); 

from(SERVICE_CONTEXT_IN).process(this.serviceProcessor); 

我在這裏的問題是,機械師如存儲要求爲Exchange媒體都在使用這種方法,任何處理器的術語「爲時已晚」在路線中已經太遲了,即,綁定已經發生並且消耗了請求。此外,CamelHttpServletRequest的InputStream已經被讀取並且不包含數據。

使用的日誌EIP的第一個位置直接地是單處理器之前:

from(SERVICE_CONTEXT_IN).log(LoggingLevel.INFO, "Request: ${in.body}") 
    .process(this.serviceProcessor); 

但是在該點的${in.body}已經是MyServiceRequest一個實例。上面添加的日誌簡單地產生Request: [email protected]。我想記錄的是在綁定到POJO之前的原始JSON。

在RestConfigurationDefinition或RestDefinition中似乎沒有啓用「原始」請求記錄的內置方式。

我可以擺脫自動JSON綁定,並手動讀取HTTP Post請求的InputStream,記錄和執行手動解組等,但我想保持內置綁定。

+0

如果你使用的是logback和jetty 7(也許是8),你可能會看看[logback-access](http://logback.qos.ch/access.html)。根據[Camel-Jetty文檔](http://camel.apache.org/jetty.html),Camel(特別是DefaultHttpBinding)會將輸入流複製到放入消息正文中的sream緩存中。從他們你可以簡單地使用'.log(LoggingLevel.Debug,「$ {in.body}」)''來記錄它。除此之外,Camel會將HTTP頭自動複製到您可以像普通交換頭一樣訪問的交換頭。 –

+0

通過記錄最初的原始請求,不能確定你的意思嗎?您可以從()中記錄原始有效負載。可以從Exchange頭文件/屬性訪問HTTP頭文件。你還想記錄什麼? –

+0

@ roman-vottner我編輯的問題包括駱駝的日誌EIP以及它不會產生預期效果的事實。儘管如此,我還沒有嘗試過logback-access。 – ahor

回答

1

在此通過不使用REST DSL與高度複雜處理器,用於記錄所述有效載荷結合I「解決」末端:

restConfiguration().component("jetty") 
    .host(this.host) 
    .port(this.port) 
    .contextPath(this.contextPath); 

rest("myService/").post() 
    .produces("application/json; charset=UTF-8") 
    .to(SERVICE_CONTEXT_IN); 

from(SERVICE_CONTEXT_IN).process(this.requestLogProcessor) 
    .unmarshal() 
    .json(JsonLibrary.Jackson, MyServiceRequest.class) 
    .process(this.serviceProcessor) 
    .marshal() 
    .json(JsonLibrary.Jackson); 

所有requestLogProcessor確實被讀取in體作爲InputStream ,獲取並記錄字符串,並最終傳遞它。

2

我同意沒有辦法使用Camel Rest端點記錄原始請求(我假定您的意思是有效負載通過任何自動綁定之前的線路)。

但考慮Roman Vottner考慮在內,你可能會改變你restConfiguration()如下:

restConfiguration().component("jetty") 
    .host(this.host) 
    .port(this.port) 
    .componentProperty("handlers", "#yourLoggingHandler") 
    .contextPath(this.contextPath) 
    .bindingMode(RestBindingMode.json); 

在您#yourLoggingHandler需要在註冊表中註冊和實施org.eclipse.jetty.server.Handler。請在Jetty文檔http://www.eclipse.org/jetty/documentation/current/jetty-handlers.html#writing-custom-handlers上撰寫自定義處理程序。

+1

我沒有測試這個,但這似乎是在使用Jetty框架機制方面的正確答案 - 儘管必須深入挖掘核心的「Handler」機制,恕我直言,IMHO僅僅是爲了獲得簡單的日誌記錄而有點超過頂端;-) – ahor