Skip to content

Commit d24747b

Browse files
committed
First commit
0 parents  commit d24747b

File tree

6 files changed

+383
-0
lines changed

6 files changed

+383
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
9+
.swiftpm/xcode/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Tech Artists Agency
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Package.resolved

Lines changed: 132 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2025 Tech Artists Agency
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
// swift-tools-version: 6.0
26+
// The swift-tools-version declares the minimum version of Swift required to build this package.
27+
28+
import PackageDescription
29+
30+
let package = Package(
31+
name: "SwiftLogCrashlyticsLogHandler",
32+
platforms: [ .iOS(.v14), .macOS(.v10_13)],
33+
products: [
34+
// Products define the executables and libraries a package produces, making them visible to other packages.
35+
.library(
36+
name: "SwiftLogCrashlyticsLogHandler",
37+
targets: ["SwiftLogCrashlyticsLogHandler"]),
38+
],
39+
dependencies: [
40+
.package(
41+
url: "https://github.com/firebase/firebase-ios-sdk.git",
42+
.upToNextMajor(from: "10.0.0")
43+
),
44+
.package(
45+
url: "https://github.com/apple/swift-log.git",
46+
from: "1.6.1"
47+
)
48+
],
49+
targets: [
50+
// Targets are the basic building blocks of a package, defining a module or a test suite.
51+
// Targets can depend on other targets in this package and products from dependencies.
52+
.target(
53+
name: "SwiftLogCrashlyticsLogHandler",
54+
dependencies: [
55+
.product(name:"FirebaseCore", package: "firebase-ios-sdk"),
56+
.product(name:"FirebaseCrashlytics", package: "firebase-ios-sdk"),
57+
.product(name: "Logging", package: "swift-log")
58+
]
59+
),
60+
.testTarget(
61+
name: "SwiftLogCrashlyticsLogHandlerTests",
62+
dependencies: ["SwiftLogCrashlyticsLogHandler"]
63+
),
64+
]
65+
)
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2025 Tech Artists Agency
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
// The Swift Programming Language
26+
// https://docs.swift.org/swift-book
27+
28+
import Foundation
29+
import FirebaseCrashlytics
30+
import Logging
31+
import FirebaseCore
32+
33+
public struct SwiftLogCrashlyticsLogHandler: LogHandler {
34+
public var logLevel: Logger.Level = .trace
35+
public let label: String
36+
37+
public init(label: String) {
38+
self.label = label
39+
FirebaseCore.FirebaseApp.configure()
40+
}
41+
42+
public var metadata = Logger.Metadata() {
43+
didSet {
44+
self.prettyMetadata = prettify(self.metadata)
45+
}
46+
}
47+
48+
private var prettyMetadata: String?
49+
50+
/// Logs a message to Firebase Crashlytics with metadata and additional context.
51+
public func log(
52+
level: Logger.Level,
53+
message: Logger.Message,
54+
metadata: Logger.Metadata?,
55+
source: String,
56+
file: String,
57+
function: String,
58+
line: UInt
59+
) {
60+
var combinedPrettyMetadata = self.prettyMetadata
61+
if let metadataOverride = metadata, !metadataOverride.isEmpty {
62+
combinedPrettyMetadata = self.prettify(
63+
self.metadata.merging(metadataOverride) { return $1 }
64+
)
65+
}
66+
67+
var formedMessage = message.description
68+
69+
if let combinedPrettyMetadata {
70+
formedMessage += " -- " + combinedPrettyMetadata
71+
}
72+
73+
// Construct log message with additional context information
74+
let detailedMessage = "\(formedMessage) [File: \(file), Function: \(function), Line: \(line)]"
75+
76+
// Log to Firebase Crashlytics
77+
Crashlytics.crashlytics().log(detailedMessage)
78+
79+
// If the log level is error or critical, report the issue to Crashlytics.
80+
if level == .error || level == .critical {
81+
let error = NSError(
82+
domain: "com.example.CrashlyticsLogHandler",
83+
code: errorCodeForLogLevel(level),
84+
userInfo: [NSLocalizedDescriptionKey: detailedMessage]
85+
)
86+
Crashlytics.crashlytics().record(error: error)
87+
}
88+
}
89+
90+
/// Retrieve or set metadata for logging.
91+
public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? {
92+
get {
93+
return self.metadata[metadataKey]
94+
}
95+
set {
96+
self.metadata[metadataKey] = newValue
97+
}
98+
}
99+
100+
/// Helper function to format metadata into a readable string.
101+
private func prettify(_ metadata: Logger.Metadata) -> String? {
102+
if metadata.isEmpty {
103+
return nil
104+
}
105+
return metadata.map { "\($0)=\($1)" }.joined(separator: " ")
106+
}
107+
108+
private func errorCodeForLogLevel(_ level: Logger.Level) -> Int {
109+
switch level {
110+
case .trace:
111+
return 0
112+
case .debug:
113+
return 1
114+
case .info:
115+
return 2
116+
case .notice:
117+
return 3
118+
case .warning:
119+
return 4
120+
case .error:
121+
return 5
122+
case .critical:
123+
return 6
124+
}
125+
}
126+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2025 Tech Artists Agency
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
import Testing
26+
@testable import SwiftLogCrashlyticsLogHandler
27+
28+
@Test func example() async throws {
29+
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
30+
}

0 commit comments

Comments
 (0)