diff --git a/akka-projection-core/src/main/scala/akka/projection/internal/ProjectionSettings.scala b/akka-projection-core/src/main/scala/akka/projection/internal/ProjectionSettings.scala index aed0536d6..302ee0381 100644 --- a/akka-projection-core/src/main/scala/akka/projection/internal/ProjectionSettings.scala +++ b/akka-projection-core/src/main/scala/akka/projection/internal/ProjectionSettings.scala @@ -7,11 +7,11 @@ package akka.projection.internal import scala.concurrent.duration.FiniteDuration import scala.concurrent.duration._ import scala.jdk.DurationConverters._ - import akka.actor.typed.ActorSystem import akka.annotation.InternalApi import akka.projection.HandlerRecoveryStrategy import akka.projection.Projection +import akka.stream.Attributes.LogLevels import akka.stream.RestartSettings import com.typesafe.config.Config @@ -50,7 +50,12 @@ private[projection] object ProjectionSettings { val maxRestarts = restartBackoffConfig.getInt("max-restarts") if (maxRestarts >= 0) RestartSettings(minBackoff, maxBackoff, randomFactor) else RestartSettings(minBackoff, maxBackoff, randomFactor).withMaxRestarts(maxRestarts, minBackoff) - } + }.withLogSettings( + RestartSettings.LogSettings.defaultSettings + .withLogLevel(LogLevels.Warning) + // Once we have retried many times, it could still be a transient failure but is + // more likely to be a permanent problem, so increase verbosity/include full stack trace + .withVerboseLogsAfter(5)) new ProjectionSettings( restartSettings, diff --git a/akka-projection-grpc/src/main/scala/akka/projection/grpc/consumer/scaladsl/GrpcReadJournal.scala b/akka-projection-grpc/src/main/scala/akka/projection/grpc/consumer/scaladsl/GrpcReadJournal.scala index 686c7f325..cb52b078c 100644 --- a/akka-projection-grpc/src/main/scala/akka/projection/grpc/consumer/scaladsl/GrpcReadJournal.scala +++ b/akka-projection-grpc/src/main/scala/akka/projection/grpc/consumer/scaladsl/GrpcReadJournal.scala @@ -376,11 +376,7 @@ final class GrpcReadJournal private ( .invoke(streamIn) .recover { case ex: akka.grpc.GrpcServiceException if ex.status.getCode == Status.Code.UNAVAILABLE => - // this means we couldn't connect, will be retried, relatively common, so make it less noisy, - // Users still want to be able to figure out non-transient errors, so log with full exception details at debug val port = clientSettings.servicePortName.getOrElse(clientSettings.defaultPort.toString) - if (log.isDebugEnabled) - log.debug(s"Connection to ${clientSettings.serviceName}:$port for stream id $streamId failed or lost", ex) throw new ConnectionException(clientSettings.serviceName, port, streamId) case th: Throwable => diff --git a/akka-projection-grpc/src/main/scala/akka/projection/grpc/internal/ConnectionException.scala b/akka-projection-grpc/src/main/scala/akka/projection/grpc/internal/ConnectionException.scala index 2cfb3c121..67318a9b7 100644 --- a/akka-projection-grpc/src/main/scala/akka/projection/grpc/internal/ConnectionException.scala +++ b/akka-projection-grpc/src/main/scala/akka/projection/grpc/internal/ConnectionException.scala @@ -6,12 +6,9 @@ package akka.projection.grpc.internal import akka.annotation.InternalApi -import scala.util.control.NoStackTrace - /** * INTERNAL API */ @InternalApi private[akka] final class ConnectionException(host: String, port: String, streamId: String) extends RuntimeException(s"Connection to $host:$port for stream id $streamId failed or lost, will be retried") - with NoStackTrace