#import "LoggingUtil.h" #import "AnonymousValueLogger.h" #import "AnonymousOccurrenceLogger.h" #import "Constraints.h" #import "TimeUtil.h" @implementation LoggingUtil +(id) throttleValueLogger:(id)valueLogger discardingAfterEventForDuration:(NSTimeInterval)duration { __block NSTimeInterval t = [TimeUtil time] - duration; return [AnonymousValueLogger anonymousValueLogger:^(double value) { double t2 = [TimeUtil time]; if (t2 - duration < t) return; t = t2; [valueLogger logValue:value]; }]; } +(id) throttleOccurrenceLogger:(id)occurrenceLogger discardingAfterEventForDuration:(NSTimeInterval)duration { __block NSTimeInterval t = [TimeUtil time] - duration; return [AnonymousOccurrenceLogger anonymousOccurencyLoggerWithMarker:^(id details) { double t2 = [TimeUtil time]; if (t2 - duration < t) return; t = t2; [occurrenceLogger markOccurrence:details]; }]; } +(id) getAccumulatingValueLoggerTo:(id)logging named:(id)valueIdentity from:(id)sender { __block double total = 0.0; id norm = [logging getValueLoggerForValue:valueIdentity from:sender]; return [AnonymousValueLogger anonymousValueLogger:^(double value) { total += value; [norm logValue:total]; }]; } +(id) getDifferenceValueLoggerTo:(id)logging named:(id)valueIdentity from:(id)sender { __block double previous = 0.0; __block bool hasPrevious = false; id norm = [logging getValueLoggerForValue:valueIdentity from:sender]; return [AnonymousValueLogger anonymousValueLogger:^(double value) { double d = value - previous; previous = value; if (hasPrevious) { [norm logValue:d]; } hasPrevious = true; }]; } +(id) getAveragingValueLoggerTo:(id)logging named:(id)valueIdentity from:(id)sender { __block double total = 0.0; __block NSUInteger count = 0; id norm = [logging getValueLoggerForValue:valueIdentity from:sender]; return [AnonymousValueLogger anonymousValueLogger:^(double value) { total += value; count += 1; [norm logValue:total/count]; }]; } +(id) getValueEstimateLoggerTo:(id)logging named:(id)valueIdentity from:(id)sender withEstimator:(DecayingSampleEstimator*)estimator { require(estimator != nil); id norm = [logging getValueLoggerForValue:valueIdentity from:sender]; return [AnonymousValueLogger anonymousValueLogger:^(double value) { [estimator updateWithNextSample:value]; [norm logValue:estimator.currentEstimate]; }]; } +(id) getMagnitudeDecayingToZeroValueLoggerTo:(id)logging named:(id)valueIdentity from:(id)sender withDecayFactor:(double)decayFactorPerSample { require(decayFactorPerSample <= 1); require(decayFactorPerSample >= 0); __block double decayingEstimate = 0.0; id norm = [logging getValueLoggerForValue:valueIdentity from:sender]; return [AnonymousValueLogger anonymousValueLogger:^(double value) { value = ABS(value); decayingEstimate = MAX(value, decayingEstimate*decayFactorPerSample); [norm logValue:decayingEstimate]; }]; } @end