Merge "Add buck resources to .gitignore"
diff --git a/BUCK b/BUCK
index 263b214..2e8a623 100644
--- a/BUCK
+++ b/BUCK
@@ -11,6 +11,7 @@
],
provided_deps = [
'//lib/commons:io',
+ '//lib/log:log4j'
],
)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
index 3d67d74..d55e334 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -64,8 +64,9 @@
import java.util.concurrent.TimeUnit;
class Destination {
- private static final Logger log = ReplicationQueue.log;
- private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log);
+ private static final Logger repLog = ReplicationQueue.repLog;
+ private static final ReplicationStateLogger stateLog =
+ new ReplicationStateLogger(repLog);
private final int poolThreads;
private final String poolName;
@@ -128,7 +129,7 @@
if (g != null) {
builder.add(g.getUUID());
} else {
- log.warn(String.format(
+ repLog.warn(String.format(
"Group \"%s\" not recognized, removing from authGroup", name));
}
}
@@ -472,8 +473,9 @@
} else if (remoteNameStyle.equals("basenameOnly")) {
name = FilenameUtils.getBaseName(name);
} else if (!remoteNameStyle.equals("slash")) {
- ReplicationQueue.log.debug(String.format(
- "Unknown remoteNameStyle: %s, falling back to slash", remoteNameStyle));
+ repLog.debug(String.format(
+ "Unknown remoteNameStyle: %s, falling back to slash",
+ remoteNameStyle));
}
String replacedPath = ReplicationQueue.replaceName(uri.getPath(), name,
isSingleProjectMatch());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
index 165ef03..720da54 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
@@ -21,15 +21,12 @@
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
class PushAll implements Runnable {
- private static final Logger log = LoggerFactory.getLogger(PushAll.class);
- private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log);
+ private static final ReplicationStateLogger stateLog =
+ new ReplicationStateLogger(ReplicationQueue.repLog);
interface Factory {
PushAll create(String urlMatch, ReplicationState state);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
index 43628f4..b699e0d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -34,6 +34,7 @@
import com.google.gerrit.server.git.VisibleRefFilter;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.server.util.IdGenerator;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
@@ -60,6 +61,7 @@
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.URIish;
import org.slf4j.Logger;
+import org.slf4j.MDC;
import java.io.IOException;
import java.util.Collection;
@@ -78,9 +80,11 @@
* take that lock to ensure they are working with a current view of the object.
*/
class PushOne implements ProjectRunnable {
- private static final Logger log = ReplicationQueue.log;
- private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log);
+ private static final Logger repLog = ReplicationQueue.repLog;
+ private static final ReplicationStateLogger stateLog =
+ new ReplicationStateLogger(repLog);
static final String ALL_REFS = "..all..";
+ static final String ID_MDC_KEY = "pushOneId";
interface Factory {
PushOne create(Project.NameKey d, URIish u);
@@ -108,6 +112,7 @@
LinkedListMultimap.create();
private final int maxLockRetries;
private int lockRetryCount;
+ private final int id;
@Inject
PushOne(final GitRepositoryManager grm,
@@ -119,6 +124,7 @@
final PerThreadRequestScope.Scoper ts,
final ChangeCache cc,
final ReplicationQueue rq,
+ final IdGenerator ig,
@Assisted final Project.NameKey d,
@Assisted final URIish u) {
gitManager = grm;
@@ -134,6 +140,7 @@
uri = u;
lockRetryCount = 0;
maxLockRetries = pool.getLockErrorMaxRetries();
+ id = ig.next();
}
@Override
@@ -153,10 +160,12 @@
@Override
public String toString() {
- if (retryCount == 0) {
- return "push " + uri;
+ String print = "[" + IdGenerator.format(id) + "] push " + uri;
+
+ if (retryCount > 0) {
+ print = "(retry " + retryCount + ") " + print;
}
- return "(retry " + retryCount + ") " + "push " + uri;
+ return print;
}
boolean isRetrying() {
@@ -184,10 +193,10 @@
if (ALL_REFS.equals(ref)) {
delta.clear();
pushAllRefs = true;
- log.trace("Added all refs for replication to " + uri);
+ repLog.trace("Added all refs for replication to " + uri);
} else if (!pushAllRefs) {
delta.add(ref);
- log.trace("Added ref " + ref + " for replication to " + uri);
+ repLog.trace("Added ref " + ref + " for replication to " + uri);
}
}
@@ -261,21 +270,22 @@
// we start replication (instead a new instance, with the same URI, is
// created and scheduled for a future point in time.)
//
+ MDC.put(ID_MDC_KEY, IdGenerator.format(id));
if (!pool.requestRunway(this)) {
if (!canceled) {
- log.info("Rescheduling replication to " + uri +
- " to avoid collision with an in-flight push.");
+ repLog.info("Rescheduling replication to " + uri
+ + " to avoid collision with an in-flight push.");
pool.reschedule(this, Destination.RetryReason.COLLISION);
}
return;
}
Stopwatch stopwatch = Stopwatch.createStarted();
- log.debug("Replication to " + uri + " started...");
+ repLog.info("Replication to " + uri + " started...");
try {
git = gitManager.openRepository(projectName);
runImpl();
- log.info("Replication to " + uri + " completed in "
+ repLog.info("Replication to " + uri + " completed in "
+ stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
} catch (RepositoryNotFoundException e) {
stateLog.error("Cannot replicate " + projectName
@@ -290,9 +300,8 @@
if (msg.contains("access denied")) {
createRepository();
} else {
- log.error("Cannot replicate " + projectName
- + "; Remote repository error: "
- + msg);
+ repLog.error("Cannot replicate " + projectName
+ + "; Remote repository error: " + msg);
}
} catch (NoRemoteRepositoryException e) {
@@ -304,22 +313,22 @@
Throwable cause = e.getCause();
if (cause instanceof JSchException
&& cause.getMessage().startsWith("UnknownHostKey:")) {
- log.error("Cannot replicate to " + uri + ": " + cause.getMessage());
+ repLog.error("Cannot replicate to " + uri + ": " + cause.getMessage());
} else if (e instanceof LockFailureException) {
lockRetryCount++;
// The LockFailureException message contains both URI and reason
// for this failure.
- log.error("Cannot replicate to " + e.getMessage());
+ repLog.error("Cannot replicate to " + e.getMessage());
// The remote push operation should be retried.
if (lockRetryCount <= maxLockRetries) {
pool.reschedule(this, Destination.RetryReason.TRANSPORT_ERROR);
} else {
- log.error("Giving up after " + lockRetryCount
+ repLog.error("Giving up after " + lockRetryCount
+ " of this error during replication to " + e.getMessage());
}
} else {
- log.error("Cannot replicate to " + uri, e);
+ repLog.error("Cannot replicate to " + uri, e);
// The remote push operation should be retried.
pool.reschedule(this, Destination.RetryReason.TRANSPORT_ERROR);
}
@@ -352,7 +361,7 @@
}
};
replicationQueue.onNewProjectCreated(event);
- log.warn("Missing repository created; retry replication to " + uri);
+ repLog.warn("Missing repository created; retry replication to " + uri);
pool.reschedule(this, Destination.RetryReason.REPOSITORY_MISSING);
} catch (IOException ioe) {
stateLog.error("Cannot replicate to " + uri + "; failed to create missing repository",
@@ -372,7 +381,7 @@
try {
tn.close();
} catch (Throwable e2) {
- log.warn("Unexpected error while closing " + uri, e2);
+ repLog.warn("Unexpected error while closing " + uri, e2);
}
}
@@ -393,7 +402,7 @@
return new PushResult();
}
- log.info("Push to " + uri + " references: " + todo);
+ repLog.info("Push to " + uri + " references: " + todo);
return tn.push(NullProgressMonitor.INSTANCE, todo);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationLogFile.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationLogFile.java
new file mode 100644
index 0000000..aeb0519
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationLogFile.java
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// 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 com.googlesource.gerrit.plugins.replication;
+
+import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.server.util.SystemLog;
+import com.google.inject.Inject;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+
+public class ReplicationLogFile implements LifecycleListener {
+
+ private final SystemLog systemLog;
+
+ @Inject
+ public ReplicationLogFile(final SystemLog systemLog) {
+ this.systemLog = systemLog;
+ }
+
+ @Override
+ public void start() {
+ Logger replicationLogger =
+ LogManager.getLogger(ReplicationQueue.REPLICATION_LOG_NAME);
+ replicationLogger.removeAllAppenders();
+ replicationLogger.addAppender(systemLog.createAsyncAppender(
+ replicationLogger.getName(), new PatternLayout("[%d] [%X{"
+ + PushOne.ID_MDC_KEY + "}] %m%n")));
+ replicationLogger.setAdditivity(false);
+ }
+
+ @Override
+ public void stop() {
+ LogManager.getLogger(ReplicationQueue.repLog.getName()).removeAllAppenders();
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
index 8aa3248..6e2ffdc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
@@ -47,6 +47,8 @@
bind(LifecycleListener.class)
.annotatedWith(UniqueAnnotations.create())
.to(OnStartStop.class);
+ bind(LifecycleListener.class).annotatedWith(UniqueAnnotations.create()).to(
+ ReplicationLogFile.class);
bind(CredentialsFactory.class).to(
AutoReloadSecureCredentialsFactoryDecorator.class).in(Scopes.SINGLETON);
bind(CapabilityDefinition.class)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
index 223e597..8be6b21 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
@@ -60,8 +60,10 @@
NewProjectCreatedListener,
ProjectDeletedListener,
HeadUpdatedListener {
- static final Logger log = LoggerFactory.getLogger(ReplicationQueue.class);
- private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log);
+ static final String REPLICATION_LOG_NAME = "replication_log";
+ static final Logger repLog = LoggerFactory.getLogger(REPLICATION_LOG_NAME);
+ private static final ReplicationStateLogger stateLog =
+ new ReplicationStateLogger(repLog);
static String replaceName(String in, String name, boolean keyIsOptional) {
String key = "${name}";
@@ -102,16 +104,16 @@
running = false;
int discarded = config.shutdown();
if (discarded > 0) {
- log.warn(String.format(
- "Cancelled %d replication events during shutdown",
- discarded));
+ repLog.warn(String.format(
+ "Cancelled %d replication events during shutdown", discarded));
}
}
void scheduleFullSync(final Project.NameKey project, final String urlMatch,
ReplicationState state) {
if (!running) {
- stateLog.warn("Replication plugin did not finish startup before event", state);
+ stateLog.warn("Replication plugin did not finish startup before event",
+ state);
return;
}
@@ -170,7 +172,7 @@
return Collections.emptySet();
}
if (!running) {
- log.error("Replication plugin did not finish startup before event");
+ repLog.error("Replication plugin did not finish startup before event");
return Collections.emptySet();
}
@@ -195,20 +197,23 @@
try {
uri = new URIish(url);
} catch (URISyntaxException e) {
- log.warn(String.format("adminURL '%s' is invalid: %s", url, e.getMessage()));
+ repLog.warn(String.format("adminURL '%s' is invalid: %s", url,
+ e.getMessage()));
continue;
}
String path = replaceName(uri.getPath(), projectName.get(),
config.isSingleProjectMatch());
if (path == null) {
- log.warn(String.format("adminURL %s does not contain ${name}", uri));
+ repLog.warn(String
+ .format("adminURL %s does not contain ${name}", uri));
continue;
}
uri = uri.setPath(path);
if (!isSSH(uri)) {
- log.warn(String.format("adminURL '%s' is invalid: only SSH is supported", uri));
+ repLog.warn(String.format(
+ "adminURL '%s' is invalid: only SSH is supported", uri));
continue;
}
@@ -228,12 +233,12 @@
private void createProject(URIish replicateURI, String head) {
if (!replicateURI.isRemote()) {
createLocally(replicateURI, head);
- log.info("Created local repository: " + replicateURI);
+ repLog.info("Created local repository: " + replicateURI);
} else if (isSSH(replicateURI)) {
createRemoteSsh(replicateURI, head);
- log.info("Created remote repository: " + replicateURI);
+ repLog.info("Created remote repository: " + replicateURI);
} else {
- log.warn(String.format("Cannot create new project on remote site %s."
+ repLog.warn(String.format("Cannot create new project on remote site %s."
+ " Only local paths and SSH URLs are supported"
+ " for remote repository creation", replicateURI));
}
@@ -254,9 +259,8 @@
repo.close();
}
} catch (IOException e) {
- log.error(String.format(
- "Error creating local repository %s:\n",
- uri.getPath()), e);
+ repLog.error(String.format(
+ "Error creating local repository %s:\n", uri.getPath()), e);
}
}
@@ -272,7 +276,7 @@
try {
executeRemoteSsh(uri, cmd, errStream);
} catch (IOException e) {
- log.error(String.format(
+ repLog.error(String.format(
"Error creating remote repository at %s:\n"
+ " Exception: %s\n"
+ " Command: %s\n"
@@ -284,12 +288,12 @@
private void deleteProject(URIish replicateURI) {
if (!replicateURI.isRemote()) {
deleteLocally(replicateURI);
- log.info("Deleted local repository: " + replicateURI);
+ repLog.info("Deleted local repository: " + replicateURI);
} else if (isSSH(replicateURI)) {
deleteRemoteSsh(replicateURI);
- log.info("Deleted remote repository: " + replicateURI);
+ repLog.info("Deleted remote repository: " + replicateURI);
} else {
- log.warn(String.format("Cannot delete project on remote site %s."
+ repLog.warn(String.format("Cannot delete project on remote site %s."
+ " Only local paths and SSH URLs are supported"
+ " for remote repository deletion", replicateURI));
}
@@ -299,7 +303,7 @@
try {
recursivelyDelete(new File(uri.getPath()));
} catch (IOException e) {
- log.error(String.format(
+ repLog.error(String.format(
"Error deleting local repository %s:\n",
uri.getPath()), e);
}
@@ -330,7 +334,7 @@
try {
executeRemoteSsh(uri, cmd, errStream);
} catch (IOException e) {
- log.error(String.format(
+ repLog.error(String.format(
"Error deleting remote repository at %s:\n"
+ " Exception: %s\n"
+ " Command: %s\n"
@@ -345,9 +349,10 @@
} else if (isSSH(replicateURI)) {
updateHeadRemoteSsh(replicateURI, newHead);
} else {
- log.warn(String.format("Cannot update HEAD of project on remote site %s."
- + " Only local paths and SSH URLs are supported"
- + " for remote HEAD update.", replicateURI));
+ repLog.warn(String.format(
+ "Cannot update HEAD of project on remote site %s."
+ + " Only local paths and SSH URLs are supported"
+ + " for remote HEAD update.", replicateURI));
}
}
@@ -359,7 +364,7 @@
try {
executeRemoteSsh(uri, cmd, errStream);
} catch (IOException e) {
- log.error(String.format(
+ repLog.error(String.format(
"Error updating HEAD of remote repository at %s to %s:\n"
+ " Exception: %s\n"
+ " Command: %s\n"
@@ -380,7 +385,9 @@
repo.close();
}
} catch (IOException e) {
- log.error(String.format("Failed to update HEAD of repository %s to %s", uri.getPath(), newHead), e);
+ repLog.error(
+ String.format("Failed to update HEAD of repository %s to %s",
+ uri.getPath(), newHead), e);
}
}