Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.

Commit 8f3b434

Browse files
committed
Implement Closure Method Example and Test
1 parent f681fb1 commit 8f3b434

File tree

8 files changed

+126
-43
lines changed

8 files changed

+126
-43
lines changed

.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Example/JustLog/AppDelegate.swift

+55-24
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,23 @@ import JustLog
1111

1212
@UIApplicationMain
1313
class AppDelegate: UIResponder, UIApplicationDelegate {
14-
14+
1515
var window: UIWindow?
1616
private var sessionID = UUID().uuidString
17-
17+
1818
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
1919
setupLogger()
2020
return true
2121
}
22+
23+
struct RegexListReponse: Codable {
24+
var pattern: String
25+
var minimumLogLevel: String
26+
}
27+
28+
struct ExceptionListResponse: Codable {
29+
var value: String
30+
}
2231

2332
func applicationDidEnterBackground(_ application: UIApplication) {
2433
forceSendLogs(application)
@@ -28,9 +37,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2837
forceSendLogs(application)
2938
}
3039

31-
func redactValues(message: String, loggerExeptionList: [String], matches: [NSTextCheckingResult]) -> String {
40+
func redactValues(message: String, loggerExeptionList: [ExceptionListResponse], matches: [NSTextCheckingResult]) -> String {
3241

33-
var redactedLogMessage = logMessagePlaceholder
42+
var redactedLogMessage = message
3443

3544
for match in matches.reversed() {
3645
let key = match.range(at: 1)
@@ -39,14 +48,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3948
let keyRange = Range(key, in: redactedLogMessage)!
4049
let valueRange = Range(value, in: redactedLogMessage)!
4150

42-
for listedException in loggerExeptionList {
43-
if listedException != redactedLogMessage[valueRange] {
44-
redactedLogMessage.replaceSubrange(keyRange, with: "****")
45-
redactedLogMessage.replaceSubrange(valueRange, with: "****")
51+
for exception in loggerExeptionList {
52+
if exception.value == redactedLogMessage[valueRange] {
53+
return redactedLogMessage
4654
}
4755
}
56+
57+
var redactedKey = redactedLogMessage[keyRange]
58+
let redactedKeyStartIndex = redactedKey.index(redactedKey.startIndex, offsetBy: 1)
59+
let redactedKeyEndIndex = redactedKey.index(redactedKey.endIndex, offsetBy: -1)
60+
61+
redactedKey.replaceSubrange(redactedKeyStartIndex..<redactedKeyEndIndex, with: "***")
62+
63+
var redactedValue = redactedLogMessage[valueRange]
64+
let valueReplacementStartIndex = redactedValue.startIndex
65+
let valueReplacementEndIndex = redactedValue.endIndex
66+
67+
redactedValue.replaceSubrange(valueReplacementStartIndex..<valueReplacementEndIndex, with: "*****")
68+
69+
redactedLogMessage.replaceSubrange(valueRange, with: redactedValue)
70+
redactedLogMessage.replaceSubrange(keyRange, with: redactedKey)
71+
4872
return redactedLogMessage
4973
}
74+
return redactedLogMessage
5075
}
5176

5277
private func forceSendLogs(_ application: UIApplication) {
@@ -63,12 +88,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
6388
identifier = UIBackgroundTaskIdentifier.invalid
6489
}
6590
}
66-
67-
var regexRules = [[#"(name) = \\*"(.*?[^\\]+)"#, "function()", "minimumLevel"]]
6891

6992
private func setupLogger() {
70-
7193
let logger = Logger.shared
94+
let decoder = JSONDecoder()
7295

7396
// custom keys
7497
logger.logTypeKey = "logtype"
@@ -84,27 +107,34 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
84107
logger.logstashPort = 5052
85108
logger.logstashTimeout = 5
86109
logger.logLogstashSocketActivity = true
87-
88-
logger.sanitizer = { message, type, regexRules, loggerExeptionList in
89110

111+
112+
let regexRuleList = "[{\"pattern\": \"(name) = \\\\\\\\*\\\"(.*?[^\\\\\\\\]+)\", \"minimumLogLevel\": \"warning\"}, {\"pattern\": \"(token) = \\\\\\\\*\\\"(.*?[^\\\\\\\\]+)\", \"minimumLogLevel\": \"warning\"}]".data(using: .utf8)
113+
let sanitizationExeceptionList = "[{\"value\": \"Dan Jones\"}, {\"value\": \"Jack Jones\"}]".data(using: .utf8)
114+
115+
logger.sanitizer = { message, type in
90116
var sanitizedMessage = message
91117

92-
for pattern in regexPattern {
93-
if let regex = try? NSRegularExpression(pattern: pattern , options: NSRegularExpression.Options.caseInsensitive) {
94-
95-
let range = NSRange(message.startIndex..<message.endIndex, in: message)
96-
let matches = regex.matches(in: message, options: [], range: range)
97-
98-
sanitizedMessage = self.redactValues(message: message, loggerExeptionList: [""], matches: matches)
99-
}
100-
}
118+
guard let ruleList = try? decoder.decode([RegexListReponse].self, from: regexRuleList!) else { return "sanitizedMessage" }
119+
guard let exceptionList = try? decoder.decode([ExceptionListResponse].self, from: sanitizationExeceptionList!) else { return "sanitizedMessage" }
101120

121+
for value in ruleList {
122+
if (value.minimumLogLevel >= type.rawValue) {
123+
if let regex = try? NSRegularExpression(pattern: value.pattern , options: NSRegularExpression.Options.caseInsensitive) {
124+
125+
let range = NSRange(sanitizedMessage.startIndex..<sanitizedMessage.endIndex, in: sanitizedMessage)
126+
let matches = regex.matches(in: sanitizedMessage, options: [], range: range)
127+
128+
sanitizedMessage = self.redactValues(message: sanitizedMessage, loggerExeptionList: exceptionList, matches: matches)
129+
}
130+
}
131+
}
102132
return sanitizedMessage
103133
}
104134

105135
// logz.io support
106136
//logger.logzioToken = <logzioToken>
107-
137+
108138
// untrusted (self-signed) logstash server support
109139
//logger.allowUntrustedServer = <Bool>
110140

@@ -114,5 +144,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
114144
"session": sessionID]
115145
logger.setup()
116146
}
117-
147+
148+
118149
}

Example/JustLog/Base.lproj/Main.storyboard

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
33
<device id="retina4_7" orientation="portrait" appearance="light"/>
44
<dependencies>
55
<deployment identifier="iOS"/>
6-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
77
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
88
</dependencies>
99
<scenes>
@@ -19,71 +19,80 @@
1919
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
2020
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
2121
<subviews>
22-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rrp-iJ-eU4">
22+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rrp-iJ-eU4">
2323
<rect key="frame" x="159" y="48" width="57" height="30"/>
2424
<state key="normal" title="Verbose"/>
2525
<connections>
2626
<action selector="verbose" destination="vXZ-lx-hvc" eventType="touchUpInside" id="5OK-rH-KXb"/>
2727
</connections>
2828
</button>
29-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ll1-z3-OAf">
29+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ll1-z3-OAf">
3030
<rect key="frame" x="164.5" y="104" width="46" height="30"/>
3131
<state key="normal" title="Debug"/>
3232
<connections>
3333
<action selector="debug" destination="vXZ-lx-hvc" eventType="touchUpInside" id="1GS-vf-8Pt"/>
3434
</connections>
3535
</button>
36-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="neQ-Yi-xyi">
36+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="neQ-Yi-xyi">
3737
<rect key="frame" x="172.5" y="163" width="30" height="30"/>
3838
<state key="normal" title="Info"/>
3939
<connections>
4040
<action selector="info" destination="vXZ-lx-hvc" eventType="touchUpInside" id="VkY-L1-KH6"/>
4141
</connections>
4242
</button>
43-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1UL-fB-OMd">
43+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1UL-fB-OMd">
4444
<rect key="frame" x="159" y="222" width="57" height="30"/>
4545
<state key="normal" title="Warning"/>
4646
<connections>
4747
<action selector="warning" destination="vXZ-lx-hvc" eventType="touchUpInside" id="lul-Wg-kUQ"/>
4848
</connections>
4949
</button>
50-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Za-Cg-HkK">
50+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Za-Cg-HkK">
5151
<rect key="frame" x="170.5" y="284" width="34" height="30"/>
5252
<state key="normal" title="Error"/>
5353
<connections>
5454
<action selector="error" destination="vXZ-lx-hvc" eventType="touchUpInside" id="z1w-gh-3bK"/>
5555
</connections>
5656
</button>
57-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="END-Sx-DWU">
58-
<rect key="frame" x="148.5" y="367" width="78" height="30"/>
57+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="END-Sx-DWU">
58+
<rect key="frame" x="148.5" y="429" width="78" height="30"/>
5959
<state key="normal" title="Force Send"/>
6060
<connections>
6161
<action selector="forceSend" destination="vXZ-lx-hvc" eventType="touchUpInside" id="nIB-AB-pXp"/>
6262
</connections>
6363
</button>
64-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qem-JA-wdP">
65-
<rect key="frame" x="163.5" y="429" width="48" height="30"/>
64+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qem-JA-wdP">
65+
<rect key="frame" x="163.5" y="487" width="48" height="30"/>
6666
<state key="normal" title="Cancel"/>
6767
<connections>
6868
<action selector="cancel:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="tto-e5-FTD"/>
6969
</connections>
7070
</button>
71+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1Xz-F9-Vc3">
72+
<rect key="frame" x="108" y="375" width="158" height="30"/>
73+
<state key="normal" title="Sanitized Log Message"/>
74+
<connections>
75+
<action selector="warningSanitized" destination="vXZ-lx-hvc" eventType="touchUpInside" id="ccf-ru-wkn"/>
76+
</connections>
77+
</button>
7178
</subviews>
7279
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
7380
<constraints>
7481
<constraint firstItem="3Za-Cg-HkK" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="2wT-ei-jcp"/>
7582
<constraint firstItem="qem-JA-wdP" firstAttribute="centerX" secondItem="END-Sx-DWU" secondAttribute="centerX" id="8PS-OS-iEO"/>
7683
<constraint firstItem="Rrp-iJ-eU4" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="Dke-Cr-Ptn"/>
7784
<constraint firstItem="ll1-z3-OAf" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="IgD-dW-iMH"/>
85+
<constraint firstItem="1Xz-F9-Vc3" firstAttribute="centerX" secondItem="END-Sx-DWU" secondAttribute="centerX" id="Kib-P0-7XH"/>
7886
<constraint firstItem="1UL-fB-OMd" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="PD3-kn-ulp"/>
7987
<constraint firstItem="3Za-Cg-HkK" firstAttribute="top" secondItem="1UL-fB-OMd" secondAttribute="bottom" constant="32" id="Ru8-o6-SMT"/>
8088
<constraint firstItem="Rrp-iJ-eU4" firstAttribute="top" secondItem="jyV-Pf-zRb" secondAttribute="bottom" constant="48" id="VfJ-iA-uKM"/>
89+
<constraint firstItem="END-Sx-DWU" firstAttribute="top" secondItem="1Xz-F9-Vc3" secondAttribute="bottom" constant="24" id="aPY-R3-h87"/>
8190
<constraint firstItem="1UL-fB-OMd" firstAttribute="top" secondItem="neQ-Yi-xyi" secondAttribute="bottom" constant="29" id="eWy-rt-csD"/>
82-
<constraint firstItem="qem-JA-wdP" firstAttribute="top" secondItem="END-Sx-DWU" secondAttribute="bottom" constant="32" id="iev-ml-CKF"/>
91+
<constraint firstItem="qem-JA-wdP" firstAttribute="top" secondItem="END-Sx-DWU" secondAttribute="bottom" constant="28" id="iev-ml-CKF"/>
8392
<constraint firstItem="END-Sx-DWU" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="jkB-5t-u15"/>
8493
<constraint firstItem="neQ-Yi-xyi" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="kcu-t7-yGB"/>
8594
<constraint firstItem="ll1-z3-OAf" firstAttribute="top" secondItem="Rrp-iJ-eU4" secondAttribute="bottom" constant="26" id="mdu-nj-zQo"/>
86-
<constraint firstItem="END-Sx-DWU" firstAttribute="top" secondItem="3Za-Cg-HkK" secondAttribute="bottom" constant="53" id="vDi-xL-q9B"/>
95+
<constraint firstItem="1Xz-F9-Vc3" firstAttribute="top" secondItem="3Za-Cg-HkK" secondAttribute="bottom" constant="61" id="xGv-Sl-5k5"/>
8796
<constraint firstItem="neQ-Yi-xyi" firstAttribute="top" secondItem="ll1-z3-OAf" secondAttribute="bottom" constant="29" id="ygx-aY-glZ"/>
8897
</constraints>
8998
</view>

Example/JustLog/ViewController.swift

+7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ class ViewController: UIViewController {
3333
logNumber += 1
3434
}
3535

36+
@IBAction func warningSanitized() {
37+
let messageToSanitize = "conversation ={\\n id = \\\"123455\\\";\\n};\\n from = {\\n id = 123456;\\n name = \\\"John Smith\\\";\\n; \\n token = \\\"123456\\\";\\n"
38+
let sanitizedMessage = Logger.shared.sanitizer(messageToSanitize, Logger.LogType.warning)
39+
Logger.shared.warning(sanitizedMessage, userInfo: ["userInfo key": "userInfo value"])
40+
logNumber += 1
41+
}
42+
3643
@IBAction func error() {
3744

3845
let underlyingUnreadableUserInfoError = [

Example/Tests/LoggerTests.swift

+12
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,16 @@ class LoggerTests: XCTestCase {
9797

9898
XCTAssertTrue(sut.queuedLogs.isEmpty)
9999
}
100+
101+
func test_logger_whenLogMessagesAreSanitized_thenExpectedResultRetrived() {
102+
let sut = Logger.shared
103+
sut.setup()
104+
var message = "conversation = {name = \\\"John Smith\\\";\\n; \\n token = \\\"123453423\\\";\\n"
105+
let expectedMessage = "conversation = {n***e = \\\"*****\\\";\\n; \\n t***n = \\\"*****\\\";\\n"
106+
107+
message = sut.sanitizer(message, Logger.LogType.error)
108+
sut.error(message, error: nil, userInfo: nil, #file, #function, #line)
109+
110+
XCTAssertEqual(message, expectedMessage)
111+
}
100112
}

JustLog.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = 'JustLog'
11-
s.version = '3.5.0'
11+
s.version = '3.6.0'
1212
s.summary = 'JustLog brings logging on iOS to the next level. It supports console, file and remote Logstash logging via TCP socket with no effort.'
1313

1414
s.description = "<<-DESC

0 commit comments

Comments
 (0)