All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.logstash.logback.stacktrace.StackHasher Maven / Gradle / Ivy

/*
 * Copyright 2013-2022 the original author or authors.
 *
 * 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.
 */
package net.logstash.logback.stacktrace;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * Utility class that generates a hash from any Java {@link Throwable error}
 *
 * @author Pierre Smeyers
 */
public class StackHasher {

    private final StackElementFilter filter;

    /**
     * Constructs a {@link StackHasher} with the given filter.
     *
     * @param filter filter
     */
    public StackHasher(StackElementFilter filter) {
        this.filter = filter;
    }

    /**
     * Constructs a {@link StackHasher} using {@link StackElementFilter#withSourceInfo()} filter
     */
    public StackHasher() {
        this(StackElementFilter.withSourceInfo());
    }

    /**
     * Generates a Hexadecimal hash for the given error stack.
     * 

* Two errors with the same stack hash are most probably same errors. * * @param error the error to generate a hash from * @return the generated hexadecimal hash */ public String hexHash(Throwable error) { // compute topmost error hash, but don't queue the complete hashes chain return toHex(hash(error, null)); } /** * Generates and returns Hexadecimal hashes for the error stack and each ancestor {@link Throwable#getCause() cause}. *

* The first queue element is the stack hash for the topmost error, the next one (if any) is it's direct * {@link Throwable#getCause() cause} hash, and so on... * * @param error the error to generate a hash from * @return a Dequeue with hashes */ public Deque hexHashes(Throwable error) { Deque hexHashes = new ArrayDeque(); hash(error, hexHashes); return hexHashes; } /** * Generates a hash (int) of the given error stack. *

* Two errors with the same stack hash are most probably same errors. * * @param error the error to generate a hash from * @param hexHashes * @return the generated hexadecimal hash */ int hash(Throwable error, Deque hexHashes) { int hash = 0; // compute parent error hash if (error.getCause() != null && error.getCause() != error) { // has parent error hash = hash(error.getCause(), hexHashes); } // then this error hash // hash error classname hash = 31 * hash + error.getClass().getName().hashCode(); // hash stacktrace for (StackTraceElement element : error.getStackTrace()) { if (filter.accept(element)) { hash = 31 * hash + hash(element); } } // push hexadecimal representation of hash if (hexHashes != null) { hexHashes.push(toHex(hash)); } return hash; } String toHex(int hash) { return String.format("%08x", hash); } int hash(StackTraceElement element) { int result = element.getClassName().hashCode(); result = 31 * result + element.getMethodName().hashCode(); // let's assume filename is not necessary result = 31 * result + element.getLineNumber(); return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy