Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ implementation 'com.google.cloud:google-cloud-logging'
If you are using Gradle without BOM, add this to your dependencies

```Groovy
implementation 'com.google.cloud:google-cloud-logging:3.2.0'
implementation 'com.google.cloud:google-cloud-logging:3.3.0'
```

If you are using SBT, add this to your dependencies

```Scala
libraryDependencies += "com.google.cloud" % "google-cloud-logging" % "3.2.0"
libraryDependencies += "com.google.cloud" % "google-cloud-logging" % "3.3.0"
```

## Authentication
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.google.cloud.logging;

import static com.google.common.base.Preconditions.checkElementIndex;

import com.google.common.base.MoreObjects;
import com.google.logging.v2.LogEntrySourceLocation;
import java.io.Serializable;
Expand Down Expand Up @@ -154,4 +156,30 @@ static SourceLocation fromPb(LogEntrySourceLocation sourceLocationPb) {
.setFunction(sourceLocationPb.getFunction())
.build();
}

/**
* Creates instance of {@link SourceLocation} based on stack trace information. Caller should
* provide the level in the stack where the information can be located. The stack trace level
* should be {@code 0} to display information for the caller of the method.
*
* @param level Zero-based non-negative integer defining the level in the stack trace where {@code
* 0} is topmost element.
* @return a new instance of {@link SourceLocation} populated with file name, method and line
* number information.
* @throws IndexOutOfBoundsException if the provided {@link level} is negative or greater than the
* current call stack.
*/
static SourceLocation fromCurrentContext(int level) {
StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
Builder builder = newBuilder();
// need to take info from 1 level down the stack to compensate the call to this
// method
int indexPlus = checkElementIndex(level, stackTrace.length - 1) + 1;
StackTraceElement ste = stackTrace[indexPlus];
return builder
.setFile(ste.getFileName())
.setLine(Long.valueOf(ste.getLineNumber()))
.setFunction(ste.getMethodName())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,27 @@ public void testToAndFromPb() {
compareSourceLocation(SOURCE_LOCATION, SourceLocation.fromPb(SOURCE_LOCATION.toPb()));
}

@Test
public void testFromCurrentContext() {
StackTraceElement expectedData = (new Exception()).getStackTrace()[0];
SourceLocation data = SourceLocation.fromCurrentContext(0);
assertEquals(expectedData.getFileName(), data.getFile());
assertEquals(expectedData.getMethodName(), data.getFunction());
// mind the assertion is vs (expectedData.lineNumber + 1). it is because the source location
// info of the expectedData is one line above the source location of the tested data.
assertEquals(Long.valueOf(expectedData.getLineNumber() + 1), data.getLine());
}

@Test(expected = IndexOutOfBoundsException.class)
public void testFromCurrentContextWithNegativeLevel() {
SourceLocation.fromCurrentContext(-1);
}

@Test(expected = IndexOutOfBoundsException.class)
public void testFromCurrentContextWithVeryLargeLevel() {
SourceLocation.fromCurrentContext(10000);
}

private void compareSourceLocation(SourceLocation expected, SourceLocation value) {
assertEquals(expected, value);
assertEquals(expected.getFile(), value.getFile());
Expand Down