// Copyright 2015 The Project Buendia Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at: http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distrib- // uted under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES // OR CONDITIONS OF ANY KIND, either express or implied. See the License for // specific language governing permissions and limitations under the License. package org.openmrs.projectbuendia.webservices.rest; import org.apache.commons.lang.exception.ExceptionUtils; import org.openmrs.module.webservices.rest.web.RequestContext; import java.io.File; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; /** Logs REST API requests in detail, with timings, to a directory of log files. */ public class RequestLogger { public static final RequestLogger LOGGER = new RequestLogger("/var/log/large/requests"); /** The directory under which we write log files. */ String dir; /** Map of log filenames to Logger objects. */ Map<String, Logger> loggers = new HashMap<>(); public RequestLogger(String dir) { new File(dir).mkdirs(); this.dir = dir; } public void request(RequestContext context, Object obj, String method) { request(context, obj, method, null); } /** Emits a "start" line for an incoming request. */ public void request(RequestContext context, Object obj, String method, Object input) { request(context, obj.getClass().getName() + "." + method, input == null ? "" : "(" + input + ")"); } /** Emits a "start" line for an incoming request. */ protected void request(RequestContext context, String key, String message) { try { HttpServletRequest request = context.getRequest(); String filename = request.getRemoteAddr(); start(filename, key, "\u001b[33m" + request.getMethod() + " " + request.getRequestURI() + "\u001b[0m " + message); } catch (Exception e) { } } /** Emits a "start" line for the given key to the given log. */ protected void start(String filename, String key, String message) { getLogger(filename).start(key, message); } /** Gets or creates the Logger for a given filename. */ protected Logger getLogger(String filename) { if (!loggers.containsKey(filename)) { loggers.put(filename, new Logger(dir + "/" + filename)); } return loggers.get(filename); } /** Emits an "end" line for a successful reply. */ public void reply(RequestContext context, Object obj, String method, Object result) { reply(context, obj.getClass().getName() + "." + method, result == null ? "" : "" + result); } /** Emits an "end" line for a successful reply. */ protected void reply(RequestContext context, String key, String message) { try { HttpServletRequest request = context.getRequest(); String filename = request.getRemoteAddr(); end(filename, key, message); } catch (Exception e) { } } /** * Emits an "end" line for the given key to the given log. The Logger * records the elapsed time between start and end for each key. */ protected void end(String filename, String key, String message) { getLogger(filename).end(key, message); } /** Emits an "end" line when an exception occurs. */ public void error(RequestContext context, Object obj, String method, Exception e) { error(context, obj.getClass().getName() + "." + method, e); } /** Emits an "end" line when an exception occurs. */ protected void error(RequestContext context, String key, Exception error) { try { HttpServletRequest request = context.getRequest(); String filename = request.getRemoteAddr(); end(filename, key, ExceptionUtils.getMessage(error) + ":\n" + ExceptionUtils.getStackTrace(error)); } catch (Exception e) { } } }