Skip to content

Commit

Permalink
Merge 3518fce into 58a00c4
Browse files Browse the repository at this point in the history
  • Loading branch information
lbloder authored Oct 29, 2024
2 parents 58a00c4 + 3518fce commit 470431c
Show file tree
Hide file tree
Showing 12 changed files with 277 additions and 21 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
- `globalHubMode` used to only be a param on `Sentry.init`. To make it easier to be used in e.g. Desktop environments, we now additionally added it as an option on SentryOptions that can also be set via `sentry.properties`.
- If both the param on `Sentry.init` and the option are set, the option will win. By default the option is set to `null` meaning whatever is passed to `Sentry.init` takes effect.
- Lazy uuid generation for SentryId and SpanId ([#3770](https://github.com/getsentry/sentry-java/pull/3770))
- Faster generation of Sentry and Span IDs ([#3818](https://github.com/getsentry/sentry-java/pull/3818))
- Uses faster implementation to convert UUID to SentryID String
- Uses faster Random implementation to generate UUIDs

### Behavioural Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.sentry.MemoryCollectionData;
import io.sentry.PerformanceCollectionData;
import io.sentry.SentryLevel;
import io.sentry.SentryUUID;
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
import io.sentry.profilemeasurements.ProfileMeasurement;
import io.sentry.profilemeasurements.ProfileMeasurementValue;
Expand All @@ -24,7 +25,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -137,7 +137,7 @@ public AndroidProfiler(
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.LOLLIPOP) return null;

// We create a file with a uuid name, so no need to check if it already exists
traceFile = new File(traceFilesDir, UUID.randomUUID() + ".trace");
traceFile = new File(traceFilesDir, SentryUUID.generateSentryId() + ".trace");

measurementsMap.clear();
screenFrameRateMeasurements.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import android.content.Context;
import io.sentry.ISentryLifecycleToken;
import io.sentry.SentryUUID;
import io.sentry.util.AutoClosableReentrantLock;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.util.UUID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
Expand Down Expand Up @@ -65,7 +65,7 @@ public static String id(final @NotNull Context context) throws RuntimeException
static @NotNull String writeInstallationFile(final @NotNull File installation)
throws IOException {
try (final OutputStream out = new FileOutputStream(installation)) {
final String id = UUID.randomUUID().toString();
final String id = SentryUUID.generateSentryId();
out.write(id.getBytes(UTF_8));
out.flush();
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
import io.sentry.ILogger;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.SentryUUID;
import io.sentry.android.core.BuildInfoProvider;
import io.sentry.android.core.ContextUtils;
import io.sentry.util.Objects;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -262,7 +262,7 @@ public void onActivityDestroyed(@NotNull Activity activity) {}
if (!isAvailable) {
return null;
}
final String uid = UUID.randomUUID().toString();
final String uid = SentryUUID.generateSentryId();
listenerMap.put(uid, listener);
trackCurrentWindow();
return uid;
Expand Down
19 changes: 19 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -3265,6 +3265,11 @@ public final class io/sentry/SentryTracer : io/sentry/ITransaction {
public fun updateEndDate (Lio/sentry/SentryDate;)Z
}

public final class io/sentry/SentryUUID {
public static fun generateSentryId ()Ljava/lang/String;
public static fun generateSpanId ()Ljava/lang/String;
}

public final class io/sentry/SentryWrapper {
public fun <init> ()V
public static fun wrapCallable (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Callable;
Expand Down Expand Up @@ -6180,6 +6185,20 @@ public final class io/sentry/util/TracingUtils$TracingHeaders {
public fun getSentryTraceHeader ()Lio/sentry/SentryTraceHeader;
}

public final class io/sentry/util/UUIDGenerator {
public fun <init> ()V
public static fun randomHalfLengthUUID ()J
public static fun randomUUID ()Ljava/util/UUID;
}

public final class io/sentry/util/UUIDStringUtils {
public fun <init> ()V
public static fun toSentryIdString (JJ)Ljava/lang/String;
public static fun toSentryIdString (Ljava/util/UUID;)Ljava/lang/String;
public static fun toSentrySpanIdString (J)Ljava/lang/String;
public static fun toSentrySpanIdString (Ljava/util/UUID;)Ljava/lang/String;
}

public final class io/sentry/util/UrlUtils {
public static final field SENSITIVE_DATA_SUBSTITUTE Ljava/lang/String;
public fun <init> ()V
Expand Down
3 changes: 1 addition & 2 deletions sentry/src/main/java/io/sentry/ProfilingTraceData.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -154,7 +153,7 @@ public ProfilingTraceData(
// Stacktrace context
this.transactionId = transactionId;
this.traceId = traceId;
this.profileId = UUID.randomUUID().toString();
this.profileId = SentryUUID.generateSentryId();
this.environment = environment != null ? environment : DEFAULT_ENVIRONMENT;
this.truncationReason = truncationReason;
if (!isTruncationReasonValid()) {
Expand Down
23 changes: 23 additions & 0 deletions sentry/src/main/java/io/sentry/SentryUUID.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.sentry;

import io.sentry.util.UUIDGenerator;
import io.sentry.util.UUIDStringUtils;

/**
* SentryUUID is a utility class for generating Sentry-specific ID Strings. It provides methods for
* generating Sentry IDs and Sentry Span IDs.
*/
public final class SentryUUID {

private SentryUUID() {
// A private constructor prevents callers from accidentally instantiating FastUUID objects
}

public static String generateSentryId() {
return UUIDStringUtils.toSentryIdString(UUIDGenerator.randomUUID());
}

public static String generateSpanId() {
return UUIDStringUtils.toSentrySpanIdString(UUIDGenerator.randomHalfLengthUUID());
}
}
11 changes: 2 additions & 9 deletions sentry/src/main/java/io/sentry/SpanId.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
import static io.sentry.util.StringUtils.PROPER_NIL_UUID;

import io.sentry.util.LazyEvaluator;
import io.sentry.util.StringUtils;
import java.io.IOException;
import java.util.Objects;
import java.util.UUID;
import org.jetbrains.annotations.NotNull;

public final class SpanId implements JsonSerializable {
public static final SpanId EMPTY_ID = new SpanId(PROPER_NIL_UUID);
public static final SpanId EMPTY_ID = new SpanId(PROPER_NIL_UUID.replace("-", ""));

private final @NotNull LazyEvaluator<String> lazyValue;

Expand All @@ -20,12 +18,7 @@ public SpanId(final @NotNull String value) {
}

public SpanId() {
this.lazyValue =
new LazyEvaluator<>(
() ->
StringUtils.normalizeUUID(UUID.randomUUID().toString())
.replace("-", "")
.substring(0, 16));
this.lazyValue = new LazyEvaluator<>(SentryUUID::generateSpanId);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions sentry/src/main/java/io/sentry/cache/EnvelopeCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.sentry.SentryItemType;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.SentryUUID;
import io.sentry.Session;
import io.sentry.UncaughtExceptionHandlerIntegration;
import io.sentry.hints.AbnormalExit;
Expand Down Expand Up @@ -45,7 +46,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -368,7 +368,7 @@ public void discard(final @NotNull SentryEnvelope envelope) {
if (fileNameMap.containsKey(envelope)) {
fileName = fileNameMap.get(envelope);
} else {
fileName = UUID.randomUUID() + SUFFIX_ENVELOPE_FILE;
fileName = SentryUUID.generateSentryId() + SUFFIX_ENVELOPE_FILE;
fileNameMap.put(envelope, fileName);
}

Expand Down
5 changes: 3 additions & 2 deletions sentry/src/main/java/io/sentry/protocol/SentryId.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.sentry.JsonSerializable;
import io.sentry.ObjectReader;
import io.sentry.ObjectWriter;
import io.sentry.SentryUUID;
import io.sentry.util.LazyEvaluator;
import io.sentry.util.StringUtils;
import java.io.IOException;
Expand All @@ -14,7 +15,7 @@

public final class SentryId implements JsonSerializable {

public static final SentryId EMPTY_ID = new SentryId(new UUID(0, 0));
public static final SentryId EMPTY_ID = new SentryId(StringUtils.PROPER_NIL_UUID);

private final @NotNull LazyEvaluator<String> lazyStringValue;

Expand All @@ -26,7 +27,7 @@ public SentryId(@Nullable UUID uuid) {
if (uuid != null) {
this.lazyStringValue = new LazyEvaluator<>(() -> normalize(uuid.toString()));
} else {
this.lazyStringValue = new LazyEvaluator<>(() -> normalize(UUID.randomUUID().toString()));
this.lazyStringValue = new LazyEvaluator<>(SentryUUID::generateSentryId);
}
}

Expand Down
77 changes: 77 additions & 0 deletions sentry/src/main/java/io/sentry/util/UUIDGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package io.sentry.util;

import java.util.Random;
import java.util.UUID;

/**
* Utility class for generating UUIDs and half-length (1 long) UUIDs. Adapted from `java.util.UUID`
* to use a faster random number generator.
*/
public final class UUIDGenerator {

@SuppressWarnings("NarrowingCompoundAssignment")
public static long randomHalfLengthUUID() {
Random random = Holder.numberGenerator;
byte[] randomBytes = new byte[8];
random.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */

long msb = 0;

for (int i = 0; i < 8; i++) msb = (msb << 8) | (randomBytes[i] & 0xff);

return msb;
}

@SuppressWarnings("NarrowingCompoundAssignment")
public static UUID randomUUID() {
Random random = Holder.numberGenerator;
byte[] randomBytes = new byte[16];
random.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= (byte) 0x80; /* set to IETF variant */

long msb = 0;
long lsb = 0;

for (int i = 0; i < 8; i++) msb = (msb << 8) | (randomBytes[i] & 0xff);

for (int i = 8; i < 16; i++) lsb = (lsb << 8) | (randomBytes[i] & 0xff);

return new UUID(msb, lsb);
}

private static class Holder {
static final Random numberGenerator = new Random();

private Holder() {}
}
}
Loading

0 comments on commit 470431c

Please sign in to comment.