aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_rewind/logging.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_rewind/logging.c')
-rw-r--r--src/bin/pg_rewind/logging.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/bin/pg_rewind/logging.c b/src/bin/pg_rewind/logging.c
new file mode 100644
index 00000000000..aba12d842ef
--- /dev/null
+++ b/src/bin/pg_rewind/logging.c
@@ -0,0 +1,140 @@
+/*-------------------------------------------------------------------------
+ *
+ * logging.c
+ * logging functions
+ *
+ * Copyright (c) 2010-2015, PostgreSQL Global Development Group
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres_fe.h"
+
+#include <unistd.h>
+#include <time.h>
+
+#include "pg_rewind.h"
+#include "logging.h"
+
+#include "pgtime.h"
+
+/* Progress counters */
+uint64 fetch_size;
+uint64 fetch_done;
+
+static pg_time_t last_progress_report = 0;
+
+#define QUERY_ALLOC 8192
+
+#define MESSAGE_WIDTH 60
+
+static
+pg_attribute_printf(2, 0)
+void
+pg_log_v(eLogType type, const char *fmt, va_list ap)
+{
+ char message[QUERY_ALLOC];
+
+ vsnprintf(message, sizeof(message), fmt, ap);
+
+ switch (type)
+ {
+ case PG_DEBUG:
+ if (debug)
+ printf("%s", _(message));
+ break;
+
+ case PG_PROGRESS:
+ if (showprogress)
+ printf("%s", _(message));
+ break;
+
+ case PG_WARNING:
+ printf("%s", _(message));
+ break;
+
+ case PG_FATAL:
+ printf("\n%s", _(message));
+ printf("%s", _("Failure, exiting\n"));
+ exit(1);
+ break;
+
+ default:
+ break;
+ }
+ fflush(stdout);
+}
+
+
+void
+pg_log(eLogType type, const char *fmt,...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ pg_log_v(type, fmt, args);
+ va_end(args);
+}
+
+
+void
+pg_fatal(const char *fmt,...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ pg_log_v(PG_FATAL, fmt, args);
+ va_end(args);
+ /* should not get here, pg_log_v() exited already */
+ exit(1);
+}
+
+
+/*
+ * Print a progress report based on the global variables.
+ *
+ * Progress report is written at maximum once per second, unless the
+ * force parameter is set to true.
+ */
+void
+progress_report(bool force)
+{
+ int percent;
+ char fetch_done_str[32];
+ char fetch_size_str[32];
+ pg_time_t now;
+
+ if (!showprogress)
+ return;
+
+ now = time(NULL);
+ if (now == last_progress_report && !force)
+ return; /* Max once per second */
+
+ last_progress_report = now;
+ percent = fetch_size ? (int) ((fetch_done) * 100 / fetch_size) : 0;
+
+ /*
+ * Avoid overflowing past 100% or the full size. This may make the total
+ * size number change as we approach the end of the backup (the estimate
+ * will always be wrong if WAL is included), but that's better than having
+ * the done column be bigger than the total.
+ */
+ if (percent > 100)
+ percent = 100;
+ if (fetch_done > fetch_size)
+ fetch_size = fetch_done;
+
+ /*
+ * Separate step to keep platform-dependent format code out of
+ * translatable strings. And we only test for INT64_FORMAT availability
+ * in snprintf, not fprintf.
+ */
+ snprintf(fetch_done_str, sizeof(fetch_done_str), INT64_FORMAT,
+ fetch_done / 1024);
+ snprintf(fetch_size_str, sizeof(fetch_size_str), INT64_FORMAT,
+ fetch_size / 1024);
+
+ pg_log(PG_PROGRESS, "%*s/%s kB (%d%%) copied\r",
+ (int) strlen(fetch_size_str), fetch_done_str, fetch_size_str,
+ percent);
+}