-
Notifications
You must be signed in to change notification settings - Fork 24
DEMRUM-773: Network Monitor Module #304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
SMickelsn
merged 27 commits into
feature/next-gen
from
feature/DEMRUM-773-Network-Info-Module
Jul 1, 2025
Merged
Changes from 11 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
0032966
DEMRUM-773 Initial Network Info method
SMickelsn ed48d3c
DEMRUM-773 Network Info module support
SMickelsn a36e67a
DEMRUM-773 Network Info module support
SMickelsn 2f2bd1f
DEMRUM-773 Network Info module support
SMickelsn eb2073f
DEMRUM-773 Network Info module support
SMickelsn 5d32b2f
DEMRUM-773 Network Info module support
SMickelsn 5b46617
DEMRUM-773 Address merge conflicts
SMickelsn 8a36b8f
DEMRUM-773 Move various files
SMickelsn 1387c06
DEMRUM-773 Move various files
SMickelsn 877915b
DEMRUM-773 Connect Module to default pool
SMickelsn 6277e4e
DEMRUM-773 Connect Module to SharedAppState
SMickelsn 338e009
DEMRUM-773 Indicate VPN as a network.connection.type
SMickelsn b77a0f6
DEMRUM-773 Return network.status as string rather than boolean
SMickelsn 7ef0816
DEMRUM-773 Remove status change span at app start
SMickelsn 3206086
DEMRUM-773 Update package.swift re review comment
SMickelsn 886d212
DEMRUM-773 Only signal change when relevant paramters change
SMickelsn 8f1d9fc
DEMRUM-773 Unit Test
SMickelsn ecdccec
Added module config. Add subtype for connection. Renamed to Network M…
aditi-s3 82d0a03
Updated package.swift and resolved conflicts
aditi-s3 8426037
Updated comments
aditi-s3 138965f
Resolved merge conflicts in files
aditi-s3 4261cdb
DEMRUM-773: Update package.swift
SMickelsn 32c4e83
DEMRUM-773: Update package.swift
SMickelsn 945ded0
Merge branch 'feature/next-gen' into feature/DEMRUM-773-Network-Info-…
SMickelsn 21b0ec1
DEMRUM-773: Updated per review comments
SMickelsn c5f0928
Merge branch 'feature/next-gen' into feature/DEMRUM-773-Network-Info-…
SMickelsn 201ea0c
DEMRUM-773: Updated per review comments
SMickelsn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
SplunkNetworkInfo/Sources/SplunkNetworkInfo/Module/NetworkInfo+Module.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// | ||
/* | ||
Copyright 2025 Splunk Inc. | ||
|
||
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 | ||
import SplunkCommon | ||
|
||
|
||
public struct NetworkInfoData: ModuleEventData {} | ||
|
||
public struct NetworkInfoMetadata: ModuleEventMetadata { | ||
public var timestamp = Date() | ||
public var eventName: String = "network.change" | ||
} | ||
|
||
extension NetworkInfo: Module { | ||
|
||
// MARK: - Module types | ||
|
||
public typealias Configuration = NetworkInfoConfiguration | ||
public typealias RemoteConfiguration = NetworkInfoRemoteConfiguration | ||
|
||
public typealias EventMetadata = NetworkInfoMetadata | ||
public typealias EventData = NetworkInfoData | ||
|
||
|
||
// MARK: - Module methods | ||
|
||
public func install(with configuration: (any ModuleConfiguration)?, remoteConfiguration: (any RemoteModuleConfiguration)?) { | ||
startDetection() | ||
} | ||
|
||
|
||
// MARK: - Type transparency helpers | ||
|
||
public func deleteData(for metadata: any ModuleEventMetadata) {} | ||
public func onPublish(data: @escaping (NetworkInfoMetadata, NetworkInfoData) -> Void) {} | ||
} |
22 changes: 22 additions & 0 deletions
22
SplunkNetworkInfo/Sources/SplunkNetworkInfo/Module/NetworkInfoConfiguration.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// | ||
/* | ||
Copyright 2025 Splunk Inc. | ||
|
||
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 | ||
import SplunkCommon | ||
|
||
/// NetworkInfo module configuration, minimal configuration for module conformance. | ||
public struct NetworkInfoConfiguration: ModuleConfiguration {} |
54 changes: 54 additions & 0 deletions
54
SplunkNetworkInfo/Sources/SplunkNetworkInfo/Module/NetworkInfoRemoteConfiguration.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// | ||
/* | ||
Copyright 2025 Splunk Inc. | ||
|
||
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 | ||
import SplunkCommon | ||
|
||
/// NetworkInfo remote configuration. | ||
public struct NetworkInfoRemoteConfiguration: RemoteModuleConfiguration { | ||
|
||
// MARK: - Internal decoding | ||
|
||
struct NetworkInfo: Decodable { | ||
let enabled: Bool | ||
} | ||
|
||
struct MRUMRoot: Decodable { | ||
let networkInfo: NetworkInfo | ||
} | ||
|
||
struct Configuration: Decodable { | ||
let mrum: MRUMRoot | ||
} | ||
|
||
struct Root: Decodable { | ||
let configuration: Configuration | ||
} | ||
|
||
|
||
// MARK: - Public | ||
|
||
public var enabled: Bool | ||
|
||
public init?(from data: Data) { | ||
guard let root = try? JSONDecoder().decode(Root.self, from: data) else { | ||
return nil | ||
} | ||
|
||
enabled = root.configuration.mrum.networkInfo.enabled | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
SplunkNetworkInfo/Sources/SplunkNetworkInfo/NetworkInfo.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// | ||
/* | ||
Copyright 2025 Splunk Inc. | ||
|
||
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 | ||
import Network | ||
import SplunkCommon | ||
import OpenTelemetryApi | ||
|
||
public class NetworkInfo { | ||
public enum ConnectionType: String { | ||
case wifi | ||
case cellular | ||
case wiredEthernet | ||
case other | ||
case lost | ||
} | ||
|
||
/// An instance of the Agent shared state object, which is used to obtain agent's state, e.g. a session id. | ||
public unowned var sharedState: AgentSharedState? | ||
|
||
public static let shared = NetworkInfo() | ||
|
||
private let monitor = NWPathMonitor() | ||
private let queue = DispatchQueue(label: "NetworkMonitorQueue") | ||
|
||
public private(set) var isConnected: Bool = false | ||
public private(set) var connectionType: ConnectionType = .lost | ||
public private(set) var isVPNActive: Bool = false | ||
|
||
public var statusChangeHandler: ((Bool, ConnectionType, Bool) -> Void)? | ||
|
||
// MARK: - Initialization | ||
|
||
// Module conformance | ||
public required init() { } | ||
|
||
public func startDetection() { | ||
monitor.pathUpdateHandler = { [weak self] path in | ||
guard let self = self else { return } | ||
self.isConnected = path.status == .satisfied | ||
self.connectionType = self.getConnectionType(path) | ||
self.isVPNActive = path.availableInterfaces.contains(where: { iface in | ||
iface.type == .other && | ||
(iface.name.lowercased().contains("utun") || | ||
iface.name.lowercased().contains("ppp") || | ||
iface.name.lowercased().contains("ipsec")) | ||
}) | ||
self.sendNetworkChangeSpan() | ||
self.statusChangeHandler?(self.isConnected, self.connectionType, self.isVPNActive) | ||
} | ||
monitor.start(queue: queue) | ||
// Send initial state span | ||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in | ||
self?.sendNetworkChangeSpan() | ||
} | ||
} | ||
|
||
private func getConnectionType(_ path: NWPath) -> ConnectionType { | ||
if path.usesInterfaceType(.wifi) { | ||
return .wifi | ||
} else if path.usesInterfaceType(.cellular) { | ||
return .cellular | ||
} else if path.usesInterfaceType(.wiredEthernet) { | ||
return .wiredEthernet | ||
} else if path.status == .unsatisfied { | ||
return .lost | ||
} else { | ||
return .other | ||
} | ||
} | ||
|
||
private func sendNetworkChangeSpan() { | ||
|
||
let tracer = OpenTelemetry.instance | ||
.tracerProvider | ||
.get( | ||
instrumentationName: "NetworkInfo", | ||
instrumentationVersion: sharedState?.agentVersion | ||
) | ||
|
||
let span = tracer.spanBuilder(spanName: "network.change") | ||
.setStartTime(time: Date()) | ||
.startSpan() | ||
span.setAttribute(key: "network.connected", value: isConnected) | ||
span.setAttribute(key: "network.connection.type", value: connectionType.rawValue) | ||
span.setAttribute(key: "network.vpn", value: isVPNActive) | ||
span.end(time: Date()) | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.