1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-15 01:04:37 +02:00

JSON output from the info command is no longer pretty-printed.

Monitoring systems can more easily ingest the JSON without linefeeds.

External tools such as jq can be used to pretty-print if desired.
This commit is contained in:
Cynthia Shang
2019-10-11 12:56:03 -04:00
committed by David Steele
parent 2972580566
commit d90b2724f8
5 changed files with 336 additions and 335 deletions

View File

@ -15,10 +15,10 @@ begin
-- Create a temp table to hold the JSON data -- Create a temp table to hold the JSON data
create temp table temp_pgbackrest_data (data jsonb); create temp table temp_pgbackrest_data (data jsonb);
-- Copy data into the table directory from the pgBackRest into command -- Copy data into the table directly from the pgBackRest info command
copy temp_pgbackrest_data (data) copy temp_pgbackrest_data (data)
from program from program
'pgbackrest --output=json info | tr ''\n'' '' ''' (format text); 'pgbackrest --output=json info' (format text);
select temp_pgbackrest_data.data select temp_pgbackrest_data.data
into data into data

View File

@ -28,6 +28,16 @@
</release-bug-list> </release-bug-list>
<release-improvement-list> <release-improvement-list>
<release-item>
<release-item-contributor-list>
<release-item-contributor id="cynthia.shang"/>
</release-item-contributor-list>
<p><proper>JSON</proper> output from the <cmd>info</cmd> command is no longer pretty-printed.</p>
<p>Monitoring systems can more easily ingest the <proper>JSON</proper> without linefeeds. External tools such as <code>jq</code> can be used to pretty-print if desired.</p>
</release-item>
<release-item> <release-item>
<release-item-contributor-list> <release-item-contributor-list>
<release-item-contributor id="cynthia.shang"/> <release-item-contributor id="cynthia.shang"/>

View File

@ -1393,15 +1393,7 @@
<p>Monitoring is an important part of any production system. There are many tools available and <backrest/> can be monitored on any of them with a little work.</p> <p>Monitoring is an important part of any production system. There are many tools available and <backrest/> can be monitored on any of them with a little work.</p>
<p><backrest/> can output information about the repository in JSON format which includes a list of all backups for each stanza and WAL archive info. A script is needed to extract information in a format that the monitoring system can understand.</p> <p><backrest/> can output information about the repository in JSON format which includes a list of all backups for each stanza and WAL archive info.</p>
<execute-list host="{[host-pg1]}">
<title>Get <backrest/> info in JSON format</title>
<execute user="postgres" show="y">
<exe-cmd>pgbackrest --output=json info</exe-cmd>
</execute>
</execute-list>
<section id="postgresql"> <section id="postgresql">
<title>In <postgres/></title> <title>In <postgres/></title>

View File

@ -800,7 +800,7 @@ infoRender(void)
} }
// Format json output // Format json output
else else
resultStr = jsonFromVar(varNewVarLst(infoList), 4); resultStr = jsonFromVar(varNewVarLst(infoList), 0);
memContextSwitch(MEM_CONTEXT_OLD()); memContextSwitch(MEM_CONTEXT_OLD());
result = strDup(resultStr); result = strDup(resultStr);

View File

@ -36,7 +36,7 @@ testRun(void)
// No stanzas have been created // No stanzas have been created
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_STR(strPtr(infoRender()), "[]\n", "json - repo but no stanzas"); TEST_RESULT_STR(strPtr(infoRender()), "[]", "json - repo but no stanzas");
harnessCfgLoad(cfgCmdInfo, argListText); harnessCfgLoad(cfgCmdInfo, argListText);
TEST_RESULT_STR(strPtr(infoRender()), "No stanzas exist in the repository.\n", "text - no stanzas"); TEST_RESULT_STR(strPtr(infoRender()), "No stanzas exist in the repository.\n", "text - no stanzas");
@ -55,19 +55,19 @@ testRun(void)
harnessCfgLoad(cfgCmdInfo, argList); harnessCfgLoad(cfgCmdInfo, argList);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
"[\n" "["
" {\n" "{"
" \"archive\" : [],\n" "\"archive\":[],"
" \"backup\" : [],\n" "\"backup\":[],"
" \"cipher\" : \"none\",\n" "\"cipher\":\"none\","
" \"db\" : [],\n" "\"db\":[],"
" \"name\" : \"stanza1\",\n" "\"name\":\"stanza1\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 3,\n" "\"code\":3,"
" \"message\" : \"missing stanza data\"\n" "\"message\":\"missing stanza data\""
" }\n" "}"
" }\n" "}"
"]\n", "json - missing stanza data"); "]", "json - missing stanza data");
// backup.info file exists, but archive.info does not // backup.info file exists, but archive.info does not
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
@ -129,39 +129,39 @@ testRun(void)
// archive section will cross reference backup db-id 2 to archive db-id 3 but db section will only use the db-ids from // archive section will cross reference backup db-id 2 to archive db-id 3 but db section will only use the db-ids from
// backup.info // backup.info
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
"[\n" "["
" {\n" "{"
" \"archive\" : [\n" "\"archive\":["
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 2\n" "\"id\":2"
" },\n" "},"
" \"id\" : \"9.4-3\",\n" "\"id\":\"9.4-3\","
" \"max\" : null,\n" "\"max\":null,"
" \"min\" : null\n" "\"min\":null"
" }\n" "}"
" ],\n" "],"
" \"backup\" : [],\n" "\"backup\":[],"
" \"cipher\" : \"aes-256-cbc\",\n" "\"cipher\":\"aes-256-cbc\","
" \"db\" : [\n" "\"db\":["
" {\n" "{"
" \"id\" : 1,\n" "\"id\":1,"
" \"system-id\" : 6569239123849665666,\n" "\"system-id\":6569239123849665666,"
" \"version\" : \"9.3\"\n" "\"version\":\"9.3\""
" },\n" "},"
" {\n" "{"
" \"id\" : 2,\n" "\"id\":2,"
" \"system-id\" : 6569239123849665679,\n" "\"system-id\":6569239123849665679,"
" \"version\" : \"9.4\"\n" "\"version\":\"9.4\""
" }\n" "}"
" ],\n" "],"
" \"name\" : \"stanza1\",\n" "\"name\":\"stanza1\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 2,\n" "\"code\":2,"
" \"message\" : \"no valid backups\"\n" "\"message\":\"no valid backups\""
" }\n" "}"
" }\n" "}"
"]\n", "json - single stanza, no valid backups"); "]", "json - single stanza, no valid backups");
harnessCfgLoad(cfgCmdInfo, argListText); harnessCfgLoad(cfgCmdInfo, argListText);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
@ -250,82 +250,82 @@ testRun(void)
harnessInfoChecksum(content)), "put backup info to file"); harnessInfoChecksum(content)), "put backup info to file");
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
"[\n" "["
" {\n" "{"
" \"archive\" : [\n" "\"archive\":["
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"id\" : \"9.4-1\",\n" "\"id\":\"9.4-1\","
" \"max\" : \"000000020000000000000003\",\n" "\"max\":\"000000020000000000000003\","
" \"min\" : \"000000010000000000000002\"\n" "\"min\":\"000000010000000000000002\""
" },\n" "},"
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 3\n" "\"id\":3"
" },\n" "},"
" \"id\" : \"9.4-3\",\n" "\"id\":\"9.4-3\","
" \"max\" : null,\n" "\"max\":null,"
" \"min\" : null\n" "\"min\":null"
" }\n" "}"
" ],\n" "],"
" \"backup\" : [\n" "\"backup\":["
" {\n" "{"
" \"archive\" : {\n" "\"archive\":{"
" \"start\" : null,\n" "\"start\":null,"
" \"stop\" : null\n" "\"stop\":null"
" },\n" "},"
" \"backrest\" : {\n" "\"backrest\":{"
" \"format\" : 5,\n" "\"format\":5,"
" \"version\" : \"2.04\"\n" "\"version\":\"2.04\""
" },\n" "},"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"info\" : {\n" "\"info\":{"
" \"delta\" : 26897030,\n" "\"delta\":26897030,"
" \"repository\" : {\n" "\"repository\":{"
" \"delta\" : 3159,\n" "\"delta\":3159,"
" \"size\" : 3159776\n" "\"size\":3159776"
" },\n" "},"
" \"size\" : 26897030\n" "\"size\":26897030"
" },\n" "},"
" \"label\" : \"20181116-154756F\",\n" "\"label\":\"20181116-154756F\","
" \"prior\" : null,\n" "\"prior\":null,"
" \"reference\" : null,\n" "\"reference\":null,"
" \"timestamp\" : {\n" "\"timestamp\":{"
" \"start\" : 1542383276,\n" "\"start\":1542383276,"
" \"stop\" : 1542383289\n" "\"stop\":1542383289"
" },\n" "},"
" \"type\" : \"full\"\n" "\"type\":\"full\""
" }\n" "}"
" ],\n" "],"
" \"cipher\" : \"none\",\n" "\"cipher\":\"none\","
" \"db\" : [\n" "\"db\":["
" {\n" "{"
" \"id\" : 1,\n" "\"id\":1,"
" \"system-id\" : 6569239123849665679,\n" "\"system-id\":6569239123849665679,"
" \"version\" : \"9.4\"\n" "\"version\":\"9.4\""
" },\n" "},"
" {\n" "{"
" \"id\" : 2,\n" "\"id\":2,"
" \"system-id\" : 6569239123849665666,\n" "\"system-id\":6569239123849665666,"
" \"version\" : \"9.3\"\n" "\"version\":\"9.3\""
" },\n" "},"
" {\n" "{"
" \"id\" : 3,\n" "\"id\":3,"
" \"system-id\" : 6569239123849665679,\n" "\"system-id\":6569239123849665679,"
" \"version\" : \"9.4\"\n" "\"version\":\"9.4\""
" }\n" "}"
" ],\n" "],"
" \"name\" : \"stanza1\",\n" "\"name\":\"stanza1\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 0,\n" "\"code\":0,"
" \"message\" : \"ok\"\n" "\"message\":\"ok\""
" }\n" "}"
" }\n" "}"
"]\n", "json - single stanza, valid backup, no priors, no archives in latest DB"); "]", "json - single stanza, valid backup, no priors, no archives in latest DB");
harnessCfgLoad(cfgCmdInfo, argListText); harnessCfgLoad(cfgCmdInfo, argListText);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
@ -575,166 +575,166 @@ testRun(void)
harnessCfgLoad(cfgCmdInfo, argList); harnessCfgLoad(cfgCmdInfo, argList);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
"[\n" "["
" {\n" "{"
" \"archive\" : [\n" "\"archive\":["
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"id\" : \"9.4-1\",\n" "\"id\":\"9.4-1\","
" \"max\" : \"000000020000000000000003\",\n" "\"max\":\"000000020000000000000003\","
" \"min\" : \"000000010000000000000002\"\n" "\"min\":\"000000010000000000000002\""
" },\n" "},"
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 2\n" "\"id\":2"
" },\n" "},"
" \"id\" : \"9.5-2\",\n" "\"id\":\"9.5-2\","
" \"max\" : null,\n" "\"max\":null,"
" \"min\" : null\n" "\"min\":null"
" }\n" "}"
" ],\n" "],"
" \"backup\" : [\n" "\"backup\":["
" {\n" "{"
" \"archive\" : {\n" "\"archive\":{"
" \"start\" : \"000000010000000000000002\",\n" "\"start\":\"000000010000000000000002\","
" \"stop\" : \"000000010000000000000002\"\n" "\"stop\":\"000000010000000000000002\""
" },\n" "},"
" \"backrest\" : {\n" "\"backrest\":{"
" \"format\" : 5,\n" "\"format\":5,"
" \"version\" : \"2.08dev\"\n" "\"version\":\"2.08dev\""
" },\n" "},"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"info\" : {\n" "\"info\":{"
" \"delta\" : 20162900,\n" "\"delta\":20162900,"
" \"repository\" : {\n" "\"repository\":{"
" \"delta\" : 2369186,\n" "\"delta\":2369186,"
" \"size\" : 2369186\n" "\"size\":2369186"
" },\n" "},"
" \"size\" : 20162900\n" "\"size\":20162900"
" },\n" "},"
" \"label\" : \"20181119-152138F\",\n" "\"label\":\"20181119-152138F\","
" \"prior\" : null,\n" "\"prior\":null,"
" \"reference\" : null,\n" "\"reference\":null,"
" \"timestamp\" : {\n" "\"timestamp\":{"
" \"start\" : 1542640898,\n" "\"start\":1542640898,"
" \"stop\" : 1542640911\n" "\"stop\":1542640911"
" },\n" "},"
" \"type\" : \"full\"\n" "\"type\":\"full\""
" },\n" "},"
" {\n" "{"
" \"archive\" : {\n" "\"archive\":{"
" \"start\" : \"000000010000000000000003\",\n" "\"start\":\"000000010000000000000003\","
" \"stop\" : \"000000010000000000000003\"\n" "\"stop\":\"000000010000000000000003\""
" },\n" "},"
" \"backrest\" : {\n" "\"backrest\":{"
" \"format\" : 5,\n" "\"format\":5,"
" \"version\" : \"2.08dev\"\n" "\"version\":\"2.08dev\""
" },\n" "},"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"info\" : {\n" "\"info\":{"
" \"delta\" : 8428,\n" "\"delta\":8428,"
" \"repository\" : {\n" "\"repository\":{"
" \"delta\" : 346,\n" "\"delta\":346,"
" \"size\" : 2369186\n" "\"size\":2369186"
" },\n" "},"
" \"size\" : 20162900\n" "\"size\":20162900"
" },\n" "},"
" \"label\" : \"20181119-152138F_20181119-152152D\",\n" "\"label\":\"20181119-152138F_20181119-152152D\","
" \"prior\" : \"20181119-152138F\",\n" "\"prior\":\"20181119-152138F\","
" \"reference\" : [\n" "\"reference\":["
" \"20181119-152138F\"\n" "\"20181119-152138F\""
" ],\n" "],"
" \"timestamp\" : {\n" "\"timestamp\":{"
" \"start\" : 1542640912,\n" "\"start\":1542640912,"
" \"stop\" : 1542640915\n" "\"stop\":1542640915"
" },\n" "},"
" \"type\" : \"diff\"\n" "\"type\":\"diff\""
" },\n" "},"
" {\n" "{"
" \"archive\" : {\n" "\"archive\":{"
" \"start\" : \"000000010000000000000003\",\n" "\"start\":\"000000010000000000000003\","
" \"stop\" : null\n" "\"stop\":null"
" },\n" "},"
" \"backrest\" : {\n" "\"backrest\":{"
" \"format\" : 5,\n" "\"format\":5,"
" \"version\" : \"2.08dev\"\n" "\"version\":\"2.08dev\""
" },\n" "},"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"info\" : {\n" "\"info\":{"
" \"delta\" : 8428,\n" "\"delta\":8428,"
" \"repository\" : {\n" "\"repository\":{"
" \"delta\" : 346,\n" "\"delta\":346,"
" \"size\" : 2369186\n" "\"size\":2369186"
" },\n" "},"
" \"size\" : 20162900\n" "\"size\":20162900"
" },\n" "},"
" \"label\" : \"20181119-152138F_20181119-152152I\",\n" "\"label\":\"20181119-152138F_20181119-152152I\","
" \"prior\" : \"20181119-152138F_20181119-152152D\",\n" "\"prior\":\"20181119-152138F_20181119-152152D\","
" \"reference\" : [\n" "\"reference\":["
" \"20181119-152138F\",\n" "\"20181119-152138F\","
" \"20181119-152138F_20181119-152152D\"\n" "\"20181119-152138F_20181119-152152D\""
" ],\n" "],"
" \"timestamp\" : {\n" "\"timestamp\":{"
" \"start\" : 1542640912,\n" "\"start\":1542640912,"
" \"stop\" : 1542640915\n" "\"stop\":1542640915"
" },\n" "},"
" \"type\" : \"incr\"\n" "\"type\":\"incr\""
" }\n" "}"
" ],\n" "],"
" \"cipher\" : \"none\",\n" "\"cipher\":\"none\","
" \"db\" : [\n" "\"db\":["
" {\n" "{"
" \"id\" : 1,\n" "\"id\":1,"
" \"system-id\" : 6625592122879095702,\n" "\"system-id\":6625592122879095702,"
" \"version\" : \"9.4\"\n" "\"version\":\"9.4\""
" },\n" "},"
" {\n" "{"
" \"id\" : 2,\n" "\"id\":2,"
" \"system-id\" : 6626363367545678089,\n" "\"system-id\":6626363367545678089,"
" \"version\" : \"9.5\"\n" "\"version\":\"9.5\""
" }\n" "}"
" ],\n" "],"
" \"name\" : \"stanza1\",\n" "\"name\":\"stanza1\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 0,\n" "\"code\":0,"
" \"message\" : \"ok\"\n" "\"message\":\"ok\""
" }\n" "}"
" },\n" "},"
" {\n" "{"
" \"archive\" : [\n" "\"archive\":["
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"id\" : \"9.4-1\",\n" "\"id\":\"9.4-1\","
" \"max\" : null,\n" "\"max\":null,"
" \"min\" : null\n" "\"min\":null"
" }\n" "}"
" ],\n" "],"
" \"backup\" : [],\n" "\"backup\":[],"
" \"cipher\" : \"none\",\n" "\"cipher\":\"none\","
" \"db\" : [\n" "\"db\":["
" {\n" "{"
" \"id\" : 1,\n" "\"id\":1,"
" \"system-id\" : 6625633699176220261,\n" "\"system-id\":6625633699176220261,"
" \"version\" : \"9.4\"\n" "\"version\":\"9.4\""
" }\n" "}"
" ],\n" "],"
" \"name\" : \"stanza2\",\n" "\"name\":\"stanza2\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 2,\n" "\"code\":2,"
" \"message\" : \"no valid backups\"\n" "\"message\":\"no valid backups\""
" }\n" "}"
" }\n" "}"
"]\n", "json - multiple stanzas, one with valid backups, archives in latest DB"); "]", "json - multiple stanzas, one with valid backups, archives in latest DB");
harnessCfgLoad(cfgCmdInfo, argListText); harnessCfgLoad(cfgCmdInfo, argListText);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
@ -918,17 +918,17 @@ testRun(void)
strLstAddZ(argList2, "--stanza=silly"); strLstAddZ(argList2, "--stanza=silly");
harnessCfgLoad(cfgCmdInfo, argList2); harnessCfgLoad(cfgCmdInfo, argList2);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
"[\n" "["
" {\n" "{"
" \"backup\" : [],\n" "\"backup\":[],"
" \"db\" : [],\n" "\"db\":[],"
" \"name\" : \"silly\",\n" "\"name\":\"silly\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 1,\n" "\"code\":1,"
" \"message\" : \"missing stanza path\"\n" "\"message\":\"missing stanza path\""
" }\n" "}"
" }\n" "}"
"]\n", "json - missing stanza path"); "]", "json - missing stanza path");
StringList *argListText2 = strLstDup(argListText); StringList *argListText2 = strLstDup(argListText);
strLstAddZ(argListText2, "--stanza=silly"); strLstAddZ(argListText2, "--stanza=silly");
@ -943,35 +943,34 @@ testRun(void)
strLstAddZ(argList, "--stanza=stanza2"); strLstAddZ(argList, "--stanza=stanza2");
harnessCfgLoad(cfgCmdInfo, argList); harnessCfgLoad(cfgCmdInfo, argList);
TEST_RESULT_STR(strPtr(infoRender()), TEST_RESULT_STR(strPtr(infoRender()),
"[\n" "["
" {\n" "{"
" \"archive\" : [\n" "\"archive\":["
" {\n" "{"
" \"database\" : {\n" "\"database\":{"
" \"id\" : 1\n" "\"id\":1"
" },\n" "},"
" \"id\" : \"9.4-1\",\n" "\"id\":\"9.4-1\","
" \"max\" : null,\n" "\"max\":null,"
" \"min\" : null\n" "\"min\":null"
" }\n" "}"
" ],\n" "],"
" \"backup\" : [],\n" "\"backup\":[],"
" \"cipher\" : \"none\",\n" "\"cipher\":\"none\","
" \"db\" : [\n" "\"db\":["
" {\n" "{"
" \"id\" : 1,\n" "\"id\":1,"
" \"system-id\" : 6625633699176220261,\n" "\"system-id\":6625633699176220261,"
" \"version\" : \"9.4\"\n" "\"version\":\"9.4\""
" }\n" "}"
" ],\n" "],"
" \"name\" : \"stanza2\",\n" "\"name\":\"stanza2\","
" \"status\" : {\n" "\"status\":{"
" \"code\" : 2,\n" "\"code\":2,"
" \"message\" : \"no valid backups\"\n" "\"message\":\"no valid backups\""
" }\n" "}"
" }\n" "}"
"]\n" "]", "json - multiple stanzas - selected found");
, "json - multiple stanzas - selected found");
strLstAddZ(argListText, "--stanza=stanza2"); strLstAddZ(argListText, "--stanza=stanza2");
harnessCfgLoad(cfgCmdInfo, argListText); harnessCfgLoad(cfgCmdInfo, argListText);