Skip to content

Commit

Permalink
Merge branch 'main' into stop_sdk_api
Browse files Browse the repository at this point in the history
# Conflicts:
#	Sources/EmbraceCore/Internal/Logs/LogController.swift
#	Sources/EmbraceCore/Session/SessionControllable.swift
#	Sources/EmbraceCore/Session/SessionController.swift
#	Tests/EmbraceCoreTests/Internal/Logs/LogControllerTests.swift
#	Tests/EmbraceOTelInternalTests/EmbraceOTelTests.swift
#	Tests/EmbraceOTelInternalTests/Logs/GenericLogExporterTests.swift
  • Loading branch information
NachoEmbrace committed Jan 21, 2025
2 parents 30c9c5b + 7e3ea2c commit 802041d
Show file tree
Hide file tree
Showing 36 changed files with 774 additions and 172 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ jobs:
- name: Record SDK Version History
if: env.IS_PRODUCTION_READY == 'true'
run: |
curl -f -X POST ${{ vars.SDK_VERSION_URL }}/ios/version/ -H 'X-Embrace-CI: ${{ secrets.SDK_VERSION_TOKEN }}' -H 'Content-Type: application/json' -d '{"version": "${{ RC_VERSION }}"}'
curl -f -X POST ${{ vars.SDK_VERSION_URL }}/ios/version/ -H 'X-Embrace-CI: ${{ secrets.SDK_VERSION_TOKEN }}' -H 'Content-Type: application/json' -d '{"version": "${{ env.RC_VERSION }}"}'
# Note: missing/removed steps from old sdk
Expand Down
30 changes: 3 additions & 27 deletions .github/workflows/run-danger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,12 @@ on:

jobs:
build:
runs-on: macos-14
runs-on: ubuntu-latest
name: "Run Danger"
steps:
- uses: actions/checkout@v4

- name: Select Xcode
# See https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md
run: |
sudo xcode-select -s /Applications/Xcode_15.4.app
xcodebuild -version
- name: Install Danger Swift
run: |
if ! which danger-swift > /dev/null; then
echo "Danger-swift is not installed; We'll try to install it."
if ! which brew > /dev/null; then
echo "Brew is not installed; cannot proceed with Danger installation."
fi
brew bundle --verbose
echo "Danger was installed successfully"
else
echo "Danger-swift is already installed"
fi
danger-swift --version
- name: Run Danger
run: danger-swift ci
- name: Run Danger Swift
uses: danger/swift@3.20.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 6.7.0
*Jan 10th, 2025**
* Features
* Improvements to the Automatic View Capture functionality, allowing attributes to be added to traces (`TTFR` and `TTI`) using the `addAttributesToTrace(_:)` method.
* Fixes
* Fixed an issue causing crashes in views controllers with very short lifecycles (particularly in hosting controllers acting as internal bridges in SwiftUI).
* Fixed a bug causing compilation issues related to the use of `DispatchQueue`.

## 6.6.0
*Dec 12th, 2024*
* Features
Expand Down
2 changes: 1 addition & 1 deletion EmbraceIO.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "EmbraceIO"
spec.version = "6.6.0"
spec.version = "6.7.0"
spec.summary = "Visibility into your users that you didn't have before."
spec.description = <<-DESC
Embrace is the only performance monitoring platform focused solely on mobile. We are built
Expand Down
2 changes: 1 addition & 1 deletion Sources/EmbraceCommonInternal/EmbraceMeta.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
// Do not edit this file manually

public class EmbraceMeta {
public static let sdkVersion = "6.6.0"
public static let sdkVersion = "6.7.0"
}
9 changes: 7 additions & 2 deletions Sources/EmbraceCore/Internal/Embrace+Setup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,17 @@ extension Embrace {

let baseUrl = EMBDevice.isDebuggerAttached ? endpoints.developmentBaseURL : endpoints.baseURL
guard let spansURL = URL.spansEndpoint(basePath: baseUrl),
let logsURL = URL.logsEndpoint(basePath: baseUrl) else {
let logsURL = URL.logsEndpoint(basePath: baseUrl),
let attachmentsURL = URL.attachmentsEndpoint(basePath: baseUrl) else {
Embrace.logger.error("Failed to initialize endpoints!")
return nil
}

let uploadEndpoints = EmbraceUpload.EndpointOptions(spansURL: spansURL, logsURL: logsURL)
let uploadEndpoints = EmbraceUpload.EndpointOptions(
spansURL: spansURL,
logsURL: logsURL,
attachmentsURL: attachmentsURL
)

// cache
guard let cacheUrl = EmbraceFileSystem.uploadsDirectoryPath(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class EmbraceLogAttributesBuilder {
session ?? sessionControllable?.currentSession
}

init(storage: EmbraceStorageMetadataFetcher,
init(storage: EmbraceStorageMetadataFetcher?,
sessionControllable: SessionControllable,
initialAttributes: [String: String]) {
self.storage = storage
Expand Down
99 changes: 99 additions & 0 deletions Sources/EmbraceCore/Internal/Logs/LogController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,23 @@ import EmbraceStorageInternal
import EmbraceUploadInternal
import EmbraceCommonInternal
import EmbraceSemantics
import EmbraceConfigInternal
import EmbraceOTelInternal

protocol LogControllable: LogBatcherDelegate {
func uploadAllPersistedLogs()
func createLog(
_ message: String,
severity: LogSeverity,
type: LogType,
timestamp: Date,
attachment: Data?,
attachmentId: String?,
attachmentUrl: URL?,
attachmentSize: Int?,
attributes: [String: String],
stackTraceBehavior: StackTraceBehavior
)
}

class LogController: LogControllable {
Expand All @@ -19,10 +33,15 @@ class LogController: LogControllable {

weak var sdkStateProvider: EmbraceSDKStateProvider?

var otel: EmbraceOTelBridge = EmbraceOTel() // var so we can inject a mock for testing

/// This will probably be injected eventually.
/// For consistency, I created a constant
static let maxLogsPerBatch: Int = 20

static let attachmentLimit: Int = 5
static let attachmentSizeLimit: Int = 1048576 // 1 MiB

init(storage: Storage?,
upload: EmbraceLogUploader?,
controller: SessionControllable) {
Expand All @@ -45,6 +64,86 @@ class LogController: LogControllable {
try? storage.removeAllLogs()
}
}

public func createLog(
_ message: String,
severity: LogSeverity,
type: LogType = .message,
timestamp: Date = Date(),
attachment: Data? = nil,
attachmentId: String? = nil,
attachmentUrl: URL? = nil,
attachmentSize: Int? = nil,
attributes: [String: String] = [:],
stackTraceBehavior: StackTraceBehavior = .default
) {
guard let sessionController = sessionController else {
return
}

// generate attributes
let attributesBuilder = EmbraceLogAttributesBuilder(
storage: storage,
sessionControllable: sessionController,
initialAttributes: attributes
)

/*
If we want to keep this method cleaner, we could move this log to `EmbraceLogAttributesBuilder`
However that would cause to always add a frame to the stacktrace.
*/
if stackTraceBehavior == .default && (severity == .warn || severity == .error) {
let stackTrace: [String] = Thread.callStackSymbols
attributesBuilder.addStackTrace(stackTrace)
}

var finalAttributes = attributesBuilder
.addLogType(type)
.addApplicationState()
.addApplicationProperties()
.addSessionIdentifier()
.build()

// handle attachment data
if let attachment = attachment {

sessionController.increaseAttachmentCount()

let id = UUID().withoutHyphen
finalAttributes[LogSemantics.keyAttachmentId] = id

let size = attachment.count
finalAttributes[LogSemantics.keyAttachmentSize] = String(size)

// check attachment count limit
if sessionController.attachmentCount >= Self.attachmentLimit {
finalAttributes[LogSemantics.keyAttachmentErrorCode] = LogSemantics.attachmentLimitReached

// check attachment size limit
} else if size > Self.attachmentSizeLimit {
finalAttributes[LogSemantics.keyAttachmentErrorCode] = LogSemantics.attachmentTooLarge
}

// upload attachment
else {
upload?.uploadAttachment(id: id, data: attachment, completion: nil)
}
}

// handle pre-uploaded attachment
else if let attachmentId = attachmentId,
let attachmentUrl = attachmentUrl {

finalAttributes[LogSemantics.keyAttachmentId] = attachmentId
finalAttributes[LogSemantics.keyAttachmentUrl] = attachmentUrl.absoluteString

if let attachmentSize = attachmentSize {
finalAttributes[LogSemantics.keyAttachmentSize] = String(attachmentSize)
}
}

otel.log(message, severity: severity, timestamp: timestamp, attributes: finalAttributes)
}
}

extension LogController {
Expand Down
103 changes: 81 additions & 22 deletions Sources/EmbraceCore/Public/Embrace+OTel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extension Embrace: EmbraceOpenTelemetry {
)
}

private var otel: EmbraceOTel { EmbraceOTel() }
var otel: EmbraceOTel { EmbraceOTel() }

/// - Parameters:
/// - instrumentationName: The name of the instrumentation library requesting the tracer.
Expand Down Expand Up @@ -118,6 +118,7 @@ extension Embrace: EmbraceOpenTelemetry {
/// - message: Body of the log.
/// - severity: `LogSeverity` for the log.
/// - attributes: Attributes for the log.
/// - stackTraceBehavior: Defines if the stack trace information should be added to the log
public func log(
_ message: String,
severity: LogSeverity,
Expand All @@ -141,37 +142,95 @@ extension Embrace: EmbraceOpenTelemetry {
/// - severity: `LogSeverity` for the log.
/// - timestamp: Timestamp for the log.
/// - attributes: Attributes for the log.
/// - stackTraceBehavior: Defines if the stack trace information should be added to the log
public func log(
_ message: String,
severity: LogSeverity,
type: LogType = .message,
timestamp: Date,
attributes: [String: String],
attributes: [String: String] = [:],
stackTraceBehavior: StackTraceBehavior = .default
) {
let attributesBuilder = EmbraceLogAttributesBuilder(
storage: storage,
sessionControllable: sessionController,
initialAttributes: attributes
logController.createLog(
message,
severity: severity,
type: type,
timestamp: timestamp,
attachment: nil,
attachmentId: nil,
attachmentUrl: nil,
attachmentSize: nil,
attributes: attributes,
stackTraceBehavior: stackTraceBehavior
)
}

/*
If we want to keep this method cleaner, we could move this log to `EmbraceLogAttributesBuilder`
However that would cause to always add a frame to the stacktrace.
*/
if stackTraceBehavior == .default && (severity == .warn || severity == .error) {
let stackTrace: [String] = Thread.callStackSymbols
attributesBuilder.addStackTrace(stackTrace)
}

let finalAttributes = attributesBuilder
.addLogType(type)
.addApplicationState()
.addApplicationProperties()
.addSessionIdentifier()
.build()
/// Creates and adds a log with the given data as an attachment for the current session span.
/// The attachment will be hosted by Embrace and will be accessible through the dashboard.
/// - Parameters:
/// - message: Body of the log.
/// - severity: `LogSeverity` for the log.
/// - timestamp: Timestamp for the log.
/// - attachment: Data of the attachment
/// - attributes: Attributes for the log.
/// - stackTraceBehavior: Defines if the stack trace information should be added to the log
public func log(
_ message: String,
severity: LogSeverity,
type: LogType = .message,
timestamp: Date = Date(),
attachment: Data,
attributes: [String: String] = [:],
stackTraceBehavior: StackTraceBehavior = .default
) {
logController.createLog(
message,
severity: severity,
type: type,
timestamp: timestamp,
attachment: attachment,
attachmentId: nil,
attachmentUrl: nil,
attachmentSize: nil,
attributes: attributes,
stackTraceBehavior: stackTraceBehavior
)
}

otel.log(message, severity: severity, attributes: finalAttributes)
/// Creates and adds a log with the given attachment info for the current session span.
/// Use this method for attachments hosted outside of Embrace.
/// - Parameters:
/// - message: Body of the log.
/// - severity: `LogSeverity` for the log.
/// - timestamp: Timestamp for the log.
/// - attachmentId: Identifier of the attachment
/// - attachmentUrl: URL to dowload the attachment data
/// - attachmentSize: Size of the attachment (optional)
/// - attributes: Attributes for the log.
/// - stackTraceBehavior: Defines if the stack trace information should be added to the log
public func log(
_ message: String,
severity: LogSeverity,
type: LogType = .message,
timestamp: Date = Date(),
attachmentId: String,
attachmentUrl: URL,
attachmentSize: Int? = nil,
attributes: [String: String],
stackTraceBehavior: StackTraceBehavior = .default
) {
logController.createLog(
message,
severity: severity,
type: type,
timestamp: timestamp,
attachment: nil,
attachmentId: attachmentId,
attachmentUrl: attachmentUrl,
attachmentSize: attachmentSize,
attributes: attributes,
stackTraceBehavior: stackTraceBehavior
)
}
}

Expand Down
3 changes: 3 additions & 0 deletions Sources/EmbraceCore/Session/SessionControllable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ protocol SessionControllable: AnyObject {
func update(state: SessionState)
func update(appTerminated: Bool)

var attachmentCount: Int { get }
func increaseAttachmentCount()

func clear()
}
Loading

0 comments on commit 802041d

Please sign in to comment.