Skip to content
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

[tycho-4.0.x] Filter duplicate resolver messages #3228

Merged
merged 1 commit into from
Dec 11, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,31 @@
*/
public interface MavenLogger {

public void error(String message);
default void error(String message) {
error(message, null);
}

public void error(String message, Throwable cause);
default void warn(String message) {
warn(message, null);
}

public void warn(String message);
default void debug(String message) {
debug(message, null);
}

public void warn(String message, Throwable cause);
void error(String message, Throwable cause);

public void info(String message);
void warn(String message, Throwable cause);

public void debug(String message);
void info(String message);

public void debug(String message, Throwable cause);
void debug(String message, Throwable cause);

public boolean isDebugEnabled();
boolean isDebugEnabled();

public boolean isExtendedDebugEnabled();
default boolean isExtendedDebugEnabled() {
return false;
}

<T> T adapt(Class<T> adapt);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,11 @@
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.tycho.MavenRepositoryLocation;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.eclipse.tycho.core.shared.MavenContext;
import org.eclipse.tycho.core.shared.MavenLogger;
import org.eclipse.tycho.osgi.adapters.MavenLoggerAdapter;
import org.eclipse.tycho.p2maven.repository.P2ArtifactRepositoryLayout;

@Component(role = MavenContext.class)
Expand All @@ -50,8 +48,9 @@ public class DefaultMavenContext implements MavenContext {
ArtifactHandlerManager artifactHandlerManager;
@Requirement
LegacySupport legacySupport;
@Requirement
Logger logger;

@Requirement(hint = FilteringMavenLogger.HINT)
MavenLogger mavenLogger;

private Properties globalProps;
private List<MavenRepositoryLocation> repositoryLocations;
Expand Down Expand Up @@ -121,8 +120,8 @@ public File getLocalRepositoryRoot() {
}

@Override
public MavenLogger getLogger() {
return new MavenLoggerAdapter(logger, false);
public synchronized MavenLogger getLogger() {
return mavenLogger;
}

@Override
Expand Down Expand Up @@ -153,15 +152,15 @@ public Collection<ReactorProject> getProjects() {

private Optional<MavenSession> getSession() {
if (legacySupport == null) {
logger.warn("Legacy support not available");
mavenLogger.warn("Legacy support not available");
return Optional.empty();
}
MavenSession session = legacySupport.getSession();
if (session == null) {
if (logger.isDebugEnabled()) {
if (mavenLogger.isDebugEnabled()) {
Thread.dumpStack();
}
logger.warn("Not called from a maven thread");
mavenLogger.warn("Not called from a maven thread");
return Optional.empty();
}
return Optional.of(session);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*******************************************************************************
* Copyright (c) 2023 Christoph Läubrich and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.osgi.configuration;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.LegacySupport;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.tycho.core.shared.MavenLogger;

/**
* A logger that filters duplicate messages from the output, each message is only printed once
*/
@Component(role = MavenLogger.class, hint = FilteringMavenLogger.HINT)
public class FilteringMavenLogger implements MavenLogger {

static final String HINT = "filtering";

@Requirement
private LegacySupport legacySupport;

@Requirement
private Logger logger;

private Map<MavenProject, Set<LogKey>> messageLogMap = new ConcurrentHashMap<>();

@Override
public void error(String message, Throwable cause) {
if (logger.isErrorEnabled() && mustLog(message, cause, 1)) {
logger.error(message, cause);
}
}

private boolean mustLog(String message, Throwable cause, int type) {
if (legacySupport == null) {
return true;
}
MavenSession session = legacySupport.getSession();
if (session == null) {
return true;
}
MavenProject project = session.getCurrentProject();
if (project == null) {
return true;
}
LogKey logKey;
if (cause == null) {
logKey = new LogKey(message, "", type);
} else {
logKey = new LogKey(message, cause.toString(), type);
}
return messageLogMap.computeIfAbsent(project, p -> ConcurrentHashMap.newKeySet()).add(logKey);
}

@Override
public void warn(String message, Throwable cause) {
if (logger.isWarnEnabled() && mustLog(message, cause, 2)) {
logger.warn(message, cause);
}
}

@Override
public void info(String message) {
if (logger.isInfoEnabled() && mustLog(message, null, 3)) {
logger.info(message);
}
}

@Override
public void debug(String message, Throwable cause) {
if (logger.isDebugEnabled() && mustLog(message, cause, 4)) {
logger.warn(message, cause);
}
}

@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}

@Override
public <T> T adapt(Class<T> adapt) {
if (adapt == Logger.class) {
return adapt.cast(logger);
}
return null;
}

private static final record LogKey(String msg, String t, int type) {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public Collection<IInstallableUnit> resolve(Map<String, String> properties, IPro
if (s.getSeverity() == IStatus.ERROR) {
Set<Explanation> explanation = getExplanation(projector); // suppress "Cannot complete the request. Generating details."
// log all transitive requirements which cannot be satisfied; this doesn't print the dependency chain from the seed to the units with missing requirements, so this is less useful than the "explanation"
logger.debug(StatusTool.collectProblems(s));
logger.debug(StatusTool.toLogMessage(s));
explainProblems(explanation, MavenLogger::error);
throw new ResolverException(explanation.stream().map(Object::toString).collect(Collectors.joining("\n")),
selectionContext.toString(), StatusTool.findException(s));
}
if (s.getSeverity() == IStatus.WARNING) {
logger.warn(StatusTool.collectProblems(s));
logger.warn(StatusTool.toLogMessage(s));
}
Collection<IInstallableUnit> newState = projector.extractSolution();

Expand Down