package com.intuit.tank.harness.logging; /* * #%L * Intuit Tank Agent (apiharness) * %% * Copyright (C) 2011 - 2015 Intuit Inc. * %% * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * #L% */ import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang3.StringUtils; import com.intuit.tank.harness.APITestHarness; import com.intuit.tank.harness.data.HDScript; import com.intuit.tank.harness.data.HDScriptGroup; import com.intuit.tank.harness.data.HDTestPlan; import com.intuit.tank.harness.data.HDValidation; import com.intuit.tank.harness.data.RequestStep; import com.intuit.tank.harness.data.TestStep; import com.intuit.tank.harness.data.ValidationData; import com.intuit.tank.harness.test.data.Variables; import com.intuit.tank.http.BaseRequest; import com.intuit.tank.logging.LogEventType; import com.intuit.tank.logging.LogFields; import com.intuit.tank.logging.LoggingProfile; import com.intuit.tank.logging.SourceType; import com.intuit.tank.script.RequestDataPhase; public class LogEvent implements Serializable { private static final long serialVersionUID = 1L; static enum HttpType { REQUEST, RESPONSE } private LoggingProfile activeProfile = LoggingProfile.STANDARD; private LogEventType eventType = LogEventType.Other; private SourceType sourceType = SourceType.agent; private String message; // message private String instanceId; // instnaceId private String publicIp; // IP of Agent private String hostname; // hostname of Agent private String jobId; // job id as seen on Tank job queue private String threadId; // thread ID to help trace events in sequence private String loggingKey; // transaction label private String projectName; // project name private String stepIndex; // request step number private TestStep step; // request step number private HDScript script; // if script groups are created within the project private HDScriptGroup group; private HDTestPlan testPlan; // if the project has multiple test plans this field can be useful private String iteration; // current iteration number private BaseRequest request; private Variables variables; // all static and dynamic parameters set by the user private String validationStatus; // if validation is not set then the field can contain value = "NA" private String transactionId; // Transaction Id private String stepGroupName; // Step group name public LogEvent() { super(); } public String buildMessage(LogEventType type, String message) { setEventType(type); setMessage(message); return buildMessage(); } public String buildMessage() { StringBuilder sb = new StringBuilder(); appendField(sb, LogFields.EventType, eventType.name()); appendField(sb, LogFields.SourceType, sourceType.name()); appendField(sb, LogFields.InstanceId, instanceId); appendField(sb, LogFields.PublicIp, publicIp); appendField(sb, LogFields.Hostname, hostname); appendField(sb, LogFields.JobId, jobId); appendField(sb, LogFields.TransactionId, transactionId); appendField(sb, LogFields.ThreadId, threadId); appendField(sb, LogFields.LoggingKey, loggingKey); appendField(sb, LogFields.ProjectName, projectName); appendField(sb, LogFields.TestPlanName, testPlan != null ? testPlan.getTestPlanName() : null); appendField(sb, LogFields.GroupName, group != null ? group.getName() : null); appendField(sb, LogFields.ScriptName, script != null ? script.getName() : null); appendField(sb, LogFields.StepName, step != null ? step.getInfo() : null); appendField(sb, LogFields.StepIndex, stepIndex); appendField(sb, LogFields.StepGroupName, stepGroupName); appendField(sb, LogFields.TestIteration, iteration); appendField(sb, LogFields.RequestUrl, buildUrl()); appendField(sb, LogFields.ValidationStatus, validationStatus); appendField(sb, LogFields.HttpResponseTime, getResponseTime()); appendField(sb, LogFields.UserVariables, getVariableValues()); appendField(sb, LogFields.ValidationCriteria, getValidationCriteria(RequestDataPhase.POST_REQUEST)); appendField(sb, LogFields.PreValidationCriteria, getValidationCriteria(RequestDataPhase.PRE_REQUEST)); appendField(sb, LogFields.HttpRequestHeaders, getHeaders(HttpType.REQUEST)); appendField(sb, LogFields.HttpRequestBody, getBody(HttpType.REQUEST)); appendField(sb, LogFields.HttpResponseHeaders, getHeaders(HttpType.RESPONSE)); appendField(sb, LogFields.HttpResponseBody, getBody(HttpType.RESPONSE)); sb.append(message); return sb.toString(); } private String getValidationCriteria(RequestDataPhase type) { StringBuilder sb = new StringBuilder(); if (step instanceof RequestStep) { RequestStep rs = (RequestStep) step; HDValidation validation = rs.getResponse().getValidation(); if (validation != null) { addValidation(sb, type, "CookieValidation", validation.getCookieValidation()); addValidation(sb, type, "HeaderValidation", validation.getHeaderValidation()); addValidation(sb, type, "BodyValidation", validation.getBodyValidation()); } } return sb.toString(); } private void addValidation(StringBuilder sb, RequestDataPhase type, String validataionType, List<ValidationData> validations) { StringBuilder vsb = new StringBuilder(); if (validations != null && !validations.isEmpty()) { for (ValidationData validation : validations) { if (validation.getPhase() == type) { appendField(vsb, validation.getKey(), validation.getValue(), validation.getCondition()); } } if (vsb.length() > 0) { sb.append(validataionType).append(" : "); sb.append(vsb.toString()); } } } private String getBody(HttpType type) { String ret = null; if (request != null) { if (type == HttpType.REQUEST) { ret = request.getBody(); } else if (request.getResponse() != null) { ret = request.getResponse().getBody(); ret = truncateBody(ret); } } return ret; } private String truncateBody(String ret) { if (ret != null) { String mimeType = request.getResponse().getHttpHeader("Content-Type"); if (LogUtil.isTextMimeType(mimeType)) { int maxBodySize = 5000; try { maxBodySize = APITestHarness.getInstance().getTankConfig().getAgentConfig() .getMaxBodyReportSize(); } catch (Exception e) { // LOG.warn("Cannot read config. Using maxBodySize of " + maxBodySize); } if (ret.length() > maxBodySize) { ret = ret.substring(0, maxBodySize) + "..."; } } else { ret = null; } } return ret; } private String getHeaders(HttpType type) { StringBuilder sb = new StringBuilder(); if (request != null) { Map<String, String> headers = null; if (type == HttpType.REQUEST) { headers = request.getHeaderInformation(); } else if (request.getResponse() != null) { headers = request.getResponse().getHeaders(); } if (headers != null) { for (Entry<String, String> entry : headers.entrySet()) { appendField(sb, entry.getKey(), entry.getValue(), " : "); } } } return sb.toString(); } private String getVariableValues() { StringBuilder sb = new StringBuilder(); if (variables != null) { for (Entry<String, String> entry : variables.getVaribleValues().entrySet()) { if (!entry.getKey().toUpperCase().startsWith("UUID_")) { // Exclude UUID variables, there are just too many. appendField(sb, entry.getKey(), entry.getValue(), "="); } } } return sb.toString(); } private String getResponseTime() { String ret = null; if (request != null && request.getResponse() != null && request.getResponse().getResponseTime() >= 0) { ret = Long.toString(request.getResponse().getResponseTime()) + " ms"; } return ret; } public String getStepGroupName() { return stepGroupName; } public void setStepGroupName(String stepGroupName) { this.stepGroupName = stepGroupName; } public String getTransactionId() { return transactionId; } public void setTransactionId(String transactionId) { this.transactionId = transactionId; } public LogEventType getEventType() { return eventType; } public void setEventType(LogEventType eventType) { this.eventType = eventType; } public SourceType getSourceType() { return sourceType; } public void setSourceType(SourceType sourceType) { this.sourceType = sourceType; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getInstanceId() { return instanceId; } public void setInstanceId(String instanceId) { this.instanceId = instanceId; } public String getPublicIp() { return publicIp; } public void setPublicIp(String publicIp) { this.publicIp = publicIp; } public String getJobId() { return jobId; } public void setJobId(String jobId) { this.jobId = jobId; } public String getThreadId() { return threadId; } public void setThreadId(String threadId) { this.threadId = threadId; } public String getLoggingKey() { return loggingKey; } public void setLoggingKey(String loggingKey) { this.loggingKey = loggingKey; } public String getProjectName() { return projectName; } public void setProjectName(String projectName) { this.projectName = projectName; } public String getStepIndex() { return stepIndex; } public void setStepIndex(String stepIndex) { this.stepIndex = stepIndex; } public TestStep getStep() { return step; } public void setStep(TestStep step) { this.step = step; this.loggingKey = null; this.request = null; this.validationStatus = null; this.transactionId = null; this.stepGroupName = null; } public HDScript getScript() { return script; } public void setScript(HDScript script) { this.script = script; setStep(null); } public HDScriptGroup getGroup() { return group; } public void setGroup(HDScriptGroup group) { this.group = group; setScript(null); } public HDTestPlan getTestPlan() { return testPlan; } public void setTestPlan(HDTestPlan testPlan) { this.testPlan = testPlan; } public String getIteration() { return iteration; } public void setIteration(String iteration) { this.iteration = iteration; } public BaseRequest getRequest() { return request; } public void setRequest(BaseRequest request) { this.request = request; } public Variables getVariables() { return variables; } public void setVariables(Variables variables) { this.variables = variables; } public String getValidationStatus() { return validationStatus; } public void setValidationStatus(String validationStatus) { this.validationStatus = validationStatus; } public String getHostname() { return hostname; } public void setHostname(String hostname) { this.hostname = hostname; } public LoggingProfile getActiveProfile() { return activeProfile != null ? activeProfile : LoggingProfile.STANDARD; } public void setActiveProfile(LoggingProfile activeProfile) { this.activeProfile = activeProfile; } private void appendField(StringBuilder sb, LogFields field, String value) { if (getActiveProfile().isFieldLogged(field)) { if (StringUtils.isNotBlank(value)) { sb.append(' ').append(StringUtils.trim(field.name())).append("=").append('"') .append(StringUtils.trim(value)).append('"').append(' '); } } } private void appendField(StringBuilder sb, String key, String value, String separator) { if (StringUtils.isNotBlank(value)) { sb.append(' ').append(StringUtils.trim(key)).append(separator).append(StringUtils.trim(value)).append(' '); } } private String buildUrl() { String ret = null; if (request != null) { ret = request.getRequestUrl(); } return ret; } }