Skip to content

Commit

Permalink
Add a metrics command to santactl (#687)
Browse files Browse the repository at this point in the history
Add a metrics command to santactl.
  • Loading branch information
pmarkowsky committed Dec 2, 2021
1 parent 10ccee9 commit 82b71c0
Show file tree
Hide file tree
Showing 13 changed files with 664 additions and 3 deletions.
3 changes: 1 addition & 2 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,7 @@ test_suite(
"//Source/common:SNTMetricSetTest",
"//Source/common:SNTPrefixTreeTest",
"//Source/common:SantaCacheTest",
"//Source/santactl:SNTCommandFileInfoTest",
"//Source/santactl:SNTCommandSyncTest",
"//Source/santactl:unit_tests",
"//Source/santad:SNTApplicationCoreMetricsTest",
"//Source/santad:SNTApplicationTest",
"//Source/santad:SNTEndpointSecurityManagerTest",
Expand Down
1 change: 1 addition & 0 deletions Source/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ objc_library(
name = "SNTMetricSet",
srcs = ["SNTMetricSet.m"],
hdrs = ["SNTMetricSet.h"],
deps = [":SNTCommonEnums"],
)

objc_library(
Expand Down
11 changes: 11 additions & 0 deletions Source/common/SNTMetricSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/// limitations under the License.

#import <Foundation/Foundation.h>
#import "SNTCommonEnums.h"

/**
* Provides an abstraction for various metric systems that will be exported to
Expand Down Expand Up @@ -48,6 +49,8 @@ typedef NS_ENUM(NSInteger, SNTMetricType) {
SNTMetricTypeCounter = 9,
};

NSString *SNTMetricMakeStringFromMetricType(SNTMetricType metricType);

@interface SNTMetric : NSObject
- (NSDictionary *)export;
@end
Expand Down Expand Up @@ -183,4 +186,12 @@ typedef NS_ENUM(NSInteger, SNTMetricType) {
- (NSDictionary *)export;
@end

// Returns a human readble string from an SNTMetricFormat type
NSString *SNTMetricStringFromMetricFormatType(SNTMetricFormatType format);

/** Normalizes dates in an exported dictionary to be ISO8601 timestamp strings in
* UTC time.
*/
NSDictionary *SNTMetricConvertDatesToISO8601Strings(NSDictionary *metrics);

NS_ASSUME_NONNULL_END
62 changes: 62 additions & 0 deletions Source/common/SNTMetricSet.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@
/// limitations under the License.

#import "SNTMetricSet.h"
#import "SNTCommonEnums.h"

NSString *SNTMetricMakeStringFromMetricType(SNTMetricType metricType) {
NSString *typeStr;
switch (metricType) {
case SNTMetricTypeConstantBool: typeStr = @"SNTMetricTypeConstantBool"; break;
case SNTMetricTypeConstantString: typeStr = @"SNTMetricTypeConstantString"; break;
case SNTMetricTypeConstantInt64: typeStr = @"SNTMetricTypeConstantInt64"; break;
case SNTMetricTypeConstantDouble: typeStr = @"SNTMetricTypeConstantDouble"; break;
case SNTMetricTypeGaugeBool: typeStr = @"SNTMetricTypeGaugeBool"; break;
case SNTMetricTypeGaugeString: typeStr = @"SNTMetricTypeGaugeString"; break;
case SNTMetricTypeGaugeInt64: typeStr = @"SNTMetricTypeGaugeInt64"; break;
case SNTMetricTypeGaugeDouble: typeStr = @"SNTMetricTypeGaugeDouble"; break;
case SNTMetricTypeCounter: typeStr = @"SNTMetricTypeCounter"; break;
default: typeStr = @"SNTMetricTypeUnknown"; break;
}
return [NSString stringWithFormat:@"%@ %ld", typeStr, metricType];
}

/**
* SNTMetricValue encapsulates the value of a metric along with the creation
Expand Down Expand Up @@ -612,4 +630,48 @@ - (NSDictionary *)export {
}
return exported;
}

// Returns a human readble string from an SNTMetricFormat type
NSString *SNTMetricStringFromMetricFormatType(SNTMetricFormatType format) {
switch (format) {
case SNTMetricFormatTypeRawJSON: return @"rawjson";
case SNTMetricFormatTypeMonarchJSON: return @"monarchjson";
default: return @"Unknown Metric Format";
}
}

NSDictionary *SNTMetricConvertDatesToISO8601Strings(NSDictionary *metrics) {
NSMutableDictionary *mutableMetrics = [metrics mutableCopy];

id formatter;

if (@available(macOS 10.13, *)) {
NSISO8601DateFormatter *isoFormatter = [[NSISO8601DateFormatter alloc] init];

isoFormatter.formatOptions =
NSISO8601DateFormatWithInternetDateTime | NSISO8601DateFormatWithFractionalSeconds;
formatter = isoFormatter;
} else {
NSDateFormatter *localFormatter = [[NSDateFormatter alloc] init];
[localFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
[localFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
formatter = localFormatter;
}

for (NSString *metricName in mutableMetrics[@"metrics"]) {
NSMutableDictionary *metric = mutableMetrics[@"metrics"][metricName];

for (NSString *field in metric[@"fields"]) {
NSMutableArray<NSMutableDictionary *> *values = metric[@"fields"][field];

[values enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
values[index][@"created"] = [formatter stringFromDate:values[index][@"created"]];
values[index][@"last_updated"] = [formatter stringFromDate:values[index][@"last_updated"]];
}];
}
}

return mutableMetrics;
}

@end
56 changes: 56 additions & 0 deletions Source/common/SNTMetricSetTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ @interface SNTMetricStringGaugeTest : XCTestCase
@interface SNTMetricSetTest : XCTestCase
@end

@interface SNTMetricSetHelperFunctionsTest : XCTestCase
@end

// Stub out NSDate's date method
@implementation NSDate (custom)

Expand Down Expand Up @@ -549,3 +552,56 @@ - (void)testExportNSDictionary {
}

@end

@implementation SNTMetricSetHelperFunctionsTest
- (void)testMakeMetricString {
NSArray<NSDictionary *> *tests = @[
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeUnknown],
@"expected" : @"SNTMetricTypeUnknown 0"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeConstantBool],
@"expected" : @"SNTMetricTypeConstantBool 1"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeConstantString],
@"expected" : @"SNTMetricTypeConstantString 2"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeConstantInt64],
@"expected" : @"SNTMetricTypeConstantInt64 3"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeConstantDouble],
@"expected" : @"SNTMetricTypeConstantDouble 4"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeGaugeBool],
@"expected" : @"SNTMetricTypeGaugeBool 5"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeGaugeString],
@"expected" : @"SNTMetricTypeGaugeString 6"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeGaugeInt64],
@"expected" : @"SNTMetricTypeGaugeInt64 7"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeGaugeDouble],
@"expected" : @"SNTMetricTypeGaugeDouble 8"
},
@{
@"input" : [NSNumber numberWithInt:SNTMetricTypeCounter],
@"expected" : @"SNTMetricTypeCounter 9"
}
];

for (NSDictionary *test in tests) {
NSString *output = SNTMetricMakeStringFromMetricType([test[@"input"] integerValue]);
XCTAssertEqualObjects(test[@"expected"], output, @"expected %@ got %@", test[@"expected"],
output);
}
}
@end
5 changes: 5 additions & 0 deletions Source/common/SNTXPCUnprivilegedControlInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
- (void)enableBundles:(void (^)(BOOL))reply;
- (void)enableTransitiveRules:(void (^)(BOOL))reply;

///
/// Metrics ops
///
- (void)metrics:(void (^)(NSDictionary *))reply;

///
/// GUI Ops
///
Expand Down
28 changes: 27 additions & 1 deletion Source/santactl/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ load("//:helper.bzl", "santa_unit_test")

licenses(["notice"])

package(default_visibility = ["//:santa_package_group"])

objc_library(
name = "santactl_lib",
srcs = [
Expand All @@ -15,6 +17,8 @@ objc_library(
"Commands/SNTCommandRule.m",
"Commands/SNTCommandStatus.m",
"Commands/SNTCommandVersion.m",
"Commands/SNTCommandMetrics.h",
"Commands/SNTCommandMetrics.m",
"Commands/sync/NSData+Zlib.h",
"Commands/sync/NSData+Zlib.m",
"Commands/sync/SNTCommandSync.m",
Expand Down Expand Up @@ -54,6 +58,7 @@ objc_library(
"//Source/common:SNTFileInfo",
"//Source/common:SNTKernelCommon",
"//Source/common:SNTLogging",
"//Source/common:SNTMetricSet",
"//Source/common:SNTRule",
"//Source/common:SNTStoredEvent",
"//Source/common:SNTStrengthify",
Expand Down Expand Up @@ -94,7 +99,6 @@ macos_command_line_application(
"//conditions:default": "Santa_Dev.provisionprofile",
}),
version = "//:version",
visibility = ["//:santa_package_group"],
deps = [":santactl_lib"],
)

Expand Down Expand Up @@ -169,3 +173,25 @@ santa_unit_test(
"@OCMock",
],
)

santa_unit_test(
name = "SNTCommandMetricsTest",
srcs = ["Commands/SNTCommandMetricsTest.m"],
structured_resources = glob(["Commands/testdata/*"]),
visibility = ["//:santa_package_group"],
deps = [
":santactl_lib",
"//Source/santametricservice/Formats:SNTMetricFormatTestHelper",
"@OCMock",
],
)

test_suite(
name = "unit_tests",
tests = [
":SNTCommandFileInfoTest",
":SNTCommandMetricsTest",
":SNTCommandSyncTest",
],
visibility = ["//:santa_package_group"],
)
22 changes: 22 additions & 0 deletions Source/santactl/Commands/SNTCommandMetrics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// Copyright 2021 Google Inc. All rights reserved.
///
/// 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
/// distributed 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 the specific language governing permissions and
/// limitations under the License.

#import <Foundation/Foundation.h>

#import "Source/santactl/SNTCommand.h"
#import "Source/santactl/SNTCommandController.h"

@interface SNTCommandMetrics : SNTCommand <SNTCommandProtocol>
- (void)prettyPrintMetrics:(NSDictionary *)metircs asJSON:(BOOL)exportJSON;
@end
Loading

0 comments on commit 82b71c0

Please sign in to comment.