use of org.commonjava.o11yphant.metrics.annotation.Measure in project indy by Commonjava.
the class ResourceManagementFilter method doFilter.
@Override
@Measure
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
logger.trace("START: {}", getClass().getSimpleName());
final HttpServletRequest hsr = (HttpServletRequest) request;
String name = Thread.currentThread().getName();
String tn = hsr.getMethod() + " " + hsr.getPathInfo() + " (" + System.currentTimeMillis() + "." + System.nanoTime() + ")";
String qs = hsr.getQueryString();
String clientAddr = hsr.getRemoteAddr();
final String xForwardFor = hsr.getHeader(X_FORWARDED_FOR);
if (xForwardFor != null) {
// OSE proxy use HTTP header 'x-forwarded-for' to represent user IP
clientAddr = xForwardFor;
}
try {
ThreadContext threadContext = ThreadContext.getContext(true);
boolean isMetered = metricsManager.isMetered(() -> RequestContextHelper.getContext(FORCE_METERED, Boolean.FALSE));
threadContext.put(IS_METERED, isMetered);
mdcManager.putUserIP(clientAddr);
mdcManager.putExtraHeaders(hsr);
mdcManager.putRequestIDs(hsr);
threadContext.put(ORIGINAL_THREAD_NAME, name);
threadContext.put(HTTP_REQUEST, hsr);
threadContext.put(METHOD_PATH_TIME, tn);
logger.debug("START request: {} (from: {})", tn, clientAddr);
Thread.currentThread().setName(tn);
RequestContextHelper.setContext(REQUEST_PHASE, REQUEST_PHASE_START);
restLogger.info("START {}{} (from: {})", hsr.getRequestURL(), qs == null ? "" : "?" + qs, clientAddr);
MDC.remove(REQUEST_PHASE);
AtomicReference<IOException> ioex = new AtomicReference<>();
AtomicReference<ServletException> seex = new AtomicReference<>();
metricsManager.wrapWithStandardMetrics(() -> {
try {
chain.doFilter(request, response);
} catch (IOException e) {
ioex.set(e);
} catch (ServletException e) {
seex.set(e);
}
return null;
}, pathClassifier(hsr.getPathInfo()));
if (ioex.get() != null) {
throw ioex.get();
}
if (seex.get() != null) {
throw seex.get();
}
} finally {
logger.debug("Cleaning up resources for thread: {}", Thread.currentThread().getName());
try {
cacheProvider.cleanupCurrentThread();
} catch (Exception e) {
logger.error("Failed to cleanup resources", e);
}
ThreadContext ctx = ThreadContext.getContext(false);
if (ctx != null) {
Map<String, Double> cumulativeTimings = (Map<String, Double>) ctx.get(CUMULATIVE_TIMINGS);
if (cumulativeTimings != null) {
cumulativeTimings.forEach((k, v) -> RequestContextHelper.setContext(CUMULATIVE_TIMINGS + "." + k, String.format("%.3f", v)));
}
Map<String, Integer> cumulativeCounts = (Map<String, Integer>) ctx.get(CUMULATIVE_COUNTS);
if (cumulativeCounts != null) {
cumulativeCounts.forEach((k, v) -> RequestContextHelper.setContext(CUMULATIVE_COUNTS + "." + k, String.format("%d", v)));
}
}
restLogger.info("END {}{} (from: {})", hsr.getRequestURL(), qs == null ? "" : "?" + qs, clientAddr);
Thread.currentThread().setName(name);
logger.debug("END request: {} (from: {})", tn, clientAddr);
mdcManager.clear();
logger.trace("END: {}", getClass().getSimpleName());
}
}
use of org.commonjava.o11yphant.metrics.annotation.Measure in project indy by Commonjava.
the class PromotionValidationTools method readPom.
@Measure
public MavenPomView readPom(final String path, final ValidationRequest request, final StoreKey... extraLocations) throws IndyWorkflowException, GalleyMavenException, IndyDataException {
ArtifactRef artifactRef = getArtifact(path);
if (artifactRef == null) {
return null;
}
Transfer transfer = retrieve(request.getSourceRepository(), path);
List<Location> locations = new ArrayList<>(extraLocations.length + 1);
locations.add(transfer.getLocation());
addLocations(locations, extraLocations);
return pomReader.read(artifactRef.asProjectVersionRef(), transfer, locations, MavenPomView.ALL_PROFILES);
}
use of org.commonjava.o11yphant.metrics.annotation.Measure in project indy by Commonjava.
the class PromotionManager method promotePaths.
/**
* Promote artifacts from the source to the target given the {@link PathsPromoteRequest}. If paths are given, promote them.
* Otherwise, build a recursive list of available artifacts in the source store and promote them.
*
* @param request containing source and target store keys, and an optional list of paths
* @return The result including the source and target store keys, the paths completed (promoted successfully),
* or errors explaining what (if anything) went wrong.
*
* IMPORTANT: Since 1.8, we use all-or-nothing policy, i.e., if anything fails we revert previous promoted paths.
*/
@Measure
public PathsPromoteResult promotePaths(final PathsPromoteRequest request, final String baseUrl) throws PromotionException, IndyWorkflowException {
RequestContextHelper.setContext(PROMOTION_ID, request.getPromotionId());
RequestContextHelper.setContext(PROMOTION_TYPE, PATH_PROMOTION);
RequestContextHelper.setContext(PROMOTION_SOURCE, request.getSource().toString());
RequestContextHelper.setContext(PROMOTION_TARGET, request.getTargetKey().toString());
Future<PathsPromoteResult> future = submitPathsPromoteRequest(request, baseUrl);
if (request.isAsync()) {
return new PathsPromoteResult(request).accepted();
} else {
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
logger.error("Path promotion failed: " + request.getSource() + " -> " + request.getTargetKey(), e);
throw new PromotionException("Execution of path promotion failed.", e);
}
}
}
use of org.commonjava.o11yphant.metrics.annotation.Measure in project indy by Commonjava.
the class PromotionValidator method validate.
/**
* NOTE: As of Indy 1.2.6, ValidationRequest passed back to enable further post-processing, especially of promotion
* paths, after promotion takes place. This enables us to avoid re-executing recursive path discovery, for instance.
*
* @param request
* @param result
* @param baseUrl
* @return
* @throws PromotionValidationException
* @throws IndyWorkflowException
*/
@Measure
public ValidationRequest validate(PromoteRequest request, ValidationResult result, String baseUrl) throws PromotionValidationException, IndyWorkflowException {
ValidationRuleSet set = validationsManager.getRuleSetMatching(request.getTargetKey());
ArtifactStore source;
try {
source = storeDataMgr.getArtifactStore(request.getSource());
} catch (IndyDataException e) {
throw new PromotionValidationException(String.format("Failed to retrieve source ArtifactStore: %s for validation", request.getSource()), e);
}
if (set != null) {
result.setRuleSet(set.getName());
RequestContextHelper.setContext(PROMOTION_VALIDATION_RULE_SET, set.getName());
logger.debug("Running validation rule-set for promotion: {}", set.getName());
List<String> ruleNames = set.getRuleNames();
if (ruleNames != null && !ruleNames.isEmpty()) {
final ArtifactStore store = getRequestStore(request, baseUrl);
final ValidationRequest req = new ValidationRequest(request, set, validationTools, store);
try {
DrainingExecutorCompletionService<Exception> svc = new DrainingExecutorCompletionService<>(validateService);
detectOverloadVoid(() -> {
for (String ruleRef : ruleNames) {
svc.submit(() -> {
RequestContextHelper.setContext(PROMOTION_VALIDATION_RULE, ruleRef);
Exception err = null;
try {
executeValidationRule(ruleRef, req, result, request);
} catch (Exception e) {
err = e;
} finally {
RequestContextHelper.clearContext(PROMOTION_VALIDATION_RULE);
}
return err;
});
}
});
List<String> errors = new ArrayList<>();
svc.drain(err -> {
if (err != null) {
logger.error("Promotion validation failure", err);
errors.add(err.getMessage());
}
});
if (!errors.isEmpty()) {
throw new PromotionValidationException(format("Failed to do promotion validation: \n\n%s", join(errors, "\n")));
}
} catch (InterruptedException e) {
throw new PromotionValidationException("Failed to do promotion validation: validation execution has been interrupted ", e);
} catch (ExecutionException e) {
throw new PromotionValidationException("Failed to execute promotion validations", e);
} finally {
if (needTempRepo(request)) {
try {
final String changeSum = format("Removes the temp remote repo [%s] after promote operation.", store);
storeDataMgr.deleteArtifactStore(store.getKey(), new ChangeSummary(ChangeSummary.SYSTEM_USER, changeSum), new EventMetadata().set(ContentManager.SUPPRESS_EVENTS, true));
Transfer root = downloadManager.getStoreRootDirectory(store);
if (root.exists()) {
root.delete(false);
}
logger.debug("Promotion temporary repo {} has been deleted for {}", store.getKey(), request.getSource());
} catch (IndyDataException | IOException e) {
logger.warn("Temporary promotion validation repository was NOT removed correctly.", e);
}
}
}
return req;
} else {
logger.info("No validation rules are defined for: {}", request.getTargetKey());
return new ValidationRequest(request, set, validationTools, source);
}
} else {
logger.info("No validation rule-sets are defined for: {}", request.getTargetKey());
return new ValidationRequest(request, set, validationTools, source);
}
}
use of org.commonjava.o11yphant.metrics.annotation.Measure in project indy by Commonjava.
the class TransferStreamingOutput method write.
@Override
@Measure
public void write(final OutputStream out) throws IOException, WebApplicationException {
start = System.nanoTime();
try {
cout = new CountingOutputStream(out);
IOUtils.copy(stream, cout);
kbCount = (double) cout.getByteCount() / 1024;
Logger logger = LoggerFactory.getLogger(getClass());
logger.trace("Wrote: {} bytes", kbCount);
long end = System.nanoTime();
RequestContextHelper.setContext(RAW_IO_WRITE_NANOS, end - start);
double elapsed = (end - start) / NANOS_PER_SEC;
TraceManager.getActiveSpan().ifPresent(s -> s.setInProgressField(LATENCY_TIMER_PAUSE_KEY, s.getInProgressField(LATENCY_TIMER_PAUSE_KEY, 0.0) + (end - start)));
String rateName = getName(metricsConfig.getNodePrefix(), TRANSFER_METRIC_NAME + WRITE_SPEED, getDefaultName(TransferStreamingOutput.class, WRITE_SPEED), METER);
Histogram rateGram = metricsManager.getHistogram(rateName);
writeSpeed = Math.round(kbCount / elapsed);
logger.info("measured speed: {} kb/s to metric: {}", (writeSpeed / 1024), rateName);
rateGram.update(writeSpeed);
String sizeName = getName(metricsConfig.getNodePrefix(), TRANSFER_METRIC_NAME + WRITE_SIZE, getDefaultName(TransferStreamingOutput.class, WRITE_SIZE), METER);
logger.info("measured size: {} kb to metric: {}", (kbCount / 1024), sizeName);
Histogram sizeGram = metricsManager.getHistogram(sizeName);
sizeGram.update(Math.round(kbCount));
} finally {
IOUtils.closeQuietly(stream);
rootSpan.ifPresent(SpanAdapter::close);
}
}
Aggregations