frontends.rst 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. .. include:: ../global.rst.inc
  2. .. highlight:: json
  3. .. _json_output:
  4. All about JSON: How to develop frontends
  5. ========================================
  6. Borg does not have a public API on the Python level. That does not keep you from writing :code:`import borg`,
  7. but does mean that there are no release-to-release guarantees on what you might find in that package, not
  8. even for point releases (1.1.x), and there is no documentation beyond the code and the internals documents.
  9. Borg does on the other hand provide an API on a command-line level. In other words, a frontend should to
  10. (for example) create a backup archive just invoke :ref:`borg_create`.
  11. Logging
  12. -------
  13. Especially for graphical frontends it is important to be able to convey and reformat progress information
  14. in meaningful ways. The ``--log-json`` option turns the stderr stream of Borg into a stream of JSON lines,
  15. where each line is a JSON object. The *type* key of the object determines its other contents.
  16. Since JSON can only encode text, any string representing a file system path may miss non-text parts.
  17. The following types are in use. Progress information is governed by the usual rules for progress information,
  18. it is not produced unless ``--progress`` is specified.
  19. archive_progress
  20. Output during operations creating archives (:ref:`borg_create` and :ref:`borg_recreate`).
  21. The following keys exist, each represents the current progress.
  22. original_size
  23. Original size of data processed so far (before compression and deduplication)
  24. compressed_size
  25. Compressed size
  26. deduplicated_size
  27. Deduplicated size
  28. nfiles
  29. Number of (regular) files processed so far
  30. path
  31. Current path
  32. progress_message
  33. A message-based progress information with no concrete progress information, just a message
  34. saying what is currently worked on.
  35. operation
  36. unique, opaque integer ID of the operation
  37. :ref:`msgid <msgid>`
  38. Message ID of the operation (may be *none*)
  39. finished
  40. boolean indicating whether the operation has finished, only the last object for an *operation*
  41. can have this property set to *true*.
  42. message
  43. current progress message (may be empty/absent)
  44. progress_percent
  45. Absolute progress information with defined end/total and current value.
  46. operation
  47. unique, opaque integer ID of the operation
  48. :ref:`msgid <msgid>`
  49. Message ID of the operation (may be *none*)
  50. finished
  51. boolean indicating whether the operation has finished, only the last object for an *operation*
  52. can have this property set to *true*.
  53. message
  54. A formatted progress message, this will include the percentage and perhaps other information
  55. current
  56. Current value (always less-or-equal to *total*)
  57. info
  58. Array that describes the current item, may be *none*, contents depend on *msgid*
  59. total
  60. Total value
  61. file_status
  62. This is only output by :ref:`borg_create` and :ref:`borg_recreate` if ``--list`` is specified. The usual
  63. rules for the file listing applies, including the ``--filter`` option.
  64. status
  65. Single-character status as for regular list output
  66. path
  67. Path of the file system object
  68. log_message
  69. Any regular log output invokes this type. Regular log options and filtering applies to these as well.
  70. created
  71. Unix timestamp (float)
  72. levelname
  73. Upper-case log level name (also called severity). Defined levels are: DEBUG, INFO, WARNING, ERROR, CRITICAL
  74. name
  75. Name of the emitting entity
  76. message
  77. Formatted log message
  78. :ref:`msgid <msgid>`
  79. Message ID, may be *none* or absent
  80. Standard output
  81. ---------------
  82. *stdout* is different and more command-dependent. Commands like :ref:`borg_info`, :ref:`borg_create`
  83. and :ref:`borg_list` implement a ``--json`` option which turns their regular output into a single JSON object.
  84. Dates are formatted according to ISO-8601 with the strftime format string '%a, %Y-%m-%d %H:%M:%S',
  85. e.g. *Sat, 2016-02-25 23:50:06*.
  86. The root object at least contains a *repository* key with an object containing:
  87. id
  88. The ID of the repository, normally 64 hex characters
  89. location
  90. Canonicalized repository path, thus this may be different from what is specified on the command line
  91. last_modified
  92. Date when the repository was last modified by the Borg client
  93. The *encryption* key, if present, contains:
  94. mode
  95. Textual encryption mode name (same as :ref:`borg_init` ``--encryption`` names)
  96. keyfile
  97. Path to the local key file used for access. Depending on *mode* this key may be absent.
  98. The *cache* key, if present, contains:
  99. path
  100. Path to the local repository cache
  101. stats
  102. Object containing cache stats:
  103. total_chunks
  104. Number of chunks
  105. total_unique_chunks
  106. Number of unique chunks
  107. total_size
  108. Total uncompressed size of all chunks multiplied with their reference counts
  109. total_csize
  110. Total compressed and encrypted size of all chunks multiplied with their reference counts
  111. unique_size
  112. Uncompressed size of all chunks
  113. unique_csize
  114. Compressed and encrypted size of all chunks
  115. Example *borg info* output::
  116. {
  117. "cache": {
  118. "path": "/home/user/.cache/borg/0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  119. "stats": {
  120. "total_chunks": 511533,
  121. "total_csize": 17948017540,
  122. "total_size": 22635749792,
  123. "total_unique_chunks": 54892,
  124. "unique_csize": 1920405405,
  125. "unique_size": 2449675468
  126. }
  127. },
  128. "encryption": {
  129. "mode": "repokey"
  130. },
  131. "repository": {
  132. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  133. "last_modified": "Mon, 2017-02-27 21:21:58",
  134. "location": "/home/user/testrepo"
  135. },
  136. "security_dir": "/home/user/.config/borg/security/0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23"
  137. }
  138. .. rubric:: Archive formats
  139. :ref:`borg_info` uses an extended format for archives, which is more expensive to retrieve, while
  140. :ref:`borg_list` uses a simpler format that is faster to retrieve. Either return archives in an
  141. array under the *archives* key, while :ref:`borg_create` returns a single archive object under the
  142. *archive* key.
  143. Both formats contain a *name* key with the archive name, the *id* key with the hexadecimal archive ID,
  144. and the *start* key with the start timestamp.
  145. info and create further have:
  146. end
  147. End timestamp
  148. duration
  149. Duration in seconds between start and end in seconds (float)
  150. stats
  151. Archive statistics (freshly calculated, this is what makes "info" more expensive)
  152. original_size
  153. Size of files and metadata before compression
  154. compressed_size
  155. Size after compression
  156. deduplicated_size
  157. Deduplicated size (against the current repository, not when the archive was created)
  158. nfiles
  159. Number of regular files in the archive
  160. limits
  161. Object describing the utilization of Borg limits
  162. max_archive_size
  163. Float between 0 and 1 describing how large this archive is relative to the maximum size allowed by Borg
  164. command_line
  165. Array of strings of the command line that created the archive
  166. The note about paths from above applies here as well.
  167. :ref:`borg_info` further has:
  168. hostname
  169. Hostname of the creating host
  170. username
  171. Name of the creating user
  172. comment
  173. Archive comment, if any
  174. Example of a simple archive listing (``borg list --last 1 --json``)::
  175. {
  176. "archives": [
  177. {
  178. "archive": "2017-02-27T21:21:51",
  179. "barchive": "2017-02-27T21:21:51",
  180. "id": "80cd07219ad725b3c5f665c1dcf119435c4dee1647a560ecac30f8d40221a46a",
  181. "name": "2017-02-27T21:21:51",
  182. "time": "Mon, 2017-02-27 21:21:52",
  183. "start": "Mon, 2017-02-27 21:21:52"
  184. }
  185. ],
  186. "encryption": {
  187. "mode": "repokey"
  188. },
  189. "repository": {
  190. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  191. "last_modified": "Mon, 2017-02-27 21:21:58",
  192. "location": "/home/user/repository"
  193. }
  194. }
  195. The same archive with more information (``borg info --last 1 --json``)::
  196. {
  197. "archives": [
  198. {
  199. "command_line": [
  200. "/home/user/.local/bin/borg",
  201. "create",
  202. "/home/user/repository",
  203. "..."
  204. ],
  205. "comment": "",
  206. "duration": 5.641542,
  207. "end": "Mon, 2017-02-27 21:21:58",
  208. "hostname": "host",
  209. "id": "80cd07219ad725b3c5f665c1dcf119435c4dee1647a560ecac30f8d40221a46a",
  210. "limits": {
  211. "max_archive_size": 0.0001330855110409714
  212. },
  213. "name": "2017-02-27T21:21:51",
  214. "start": "Mon, 2017-02-27 21:21:52",
  215. "stats": {
  216. "compressed_size": 1880961894,
  217. "deduplicated_size": 2791,
  218. "nfiles": 53669,
  219. "original_size": 2400471280
  220. },
  221. "username": "user"
  222. }
  223. ],
  224. "cache": {
  225. "path": "/home/user/.cache/borg/0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  226. "stats": {
  227. "total_chunks": 511533,
  228. "total_csize": 17948017540,
  229. "total_size": 22635749792,
  230. "total_unique_chunks": 54892,
  231. "unique_csize": 1920405405,
  232. "unique_size": 2449675468
  233. }
  234. },
  235. "encryption": {
  236. "mode": "repokey"
  237. },
  238. "repository": {
  239. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  240. "last_modified": "Mon, 2017-02-27 21:21:58",
  241. "location": "/home/user/repository"
  242. }
  243. }
  244. .. rubric:: File listings
  245. Listing the contents of an archive can produce *a lot* of JSON. Each item (file, directory, ...) is described
  246. by one object in the *files* array of the :ref:`borg_list` output. Refer to the *borg list* documentation for
  247. the available keys and their meaning.
  248. Example (excerpt)::
  249. {
  250. "encryption": {
  251. "mode": "repokey"
  252. },
  253. "repository": {
  254. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  255. "last_modified": "Mon, 2017-02-27 21:21:58",
  256. "location": "/home/user/repository"
  257. },
  258. "files": [
  259. {
  260. "type": "d",
  261. "mode": "drwxr-xr-x",
  262. "user": "user",
  263. "group": "user",
  264. "uid": 1000,
  265. "gid": 1000,
  266. "path": "linux",
  267. "healthy": true,
  268. "source": "",
  269. "linktarget": "",
  270. "flags": null,
  271. "isomtime": "Sat, 2016-05-07 19:46:01",
  272. "size": 0
  273. }
  274. ]
  275. }
  276. .. _msgid:
  277. Message IDs
  278. -----------
  279. Message IDs are strings that essentially give a log message or operation a name, without actually using the
  280. full text, since texts change more frequently. Message IDs are unambiguous and reduce the need to parse
  281. log messages.
  282. Assigned message IDs are:
  283. .. note::
  284. This list is incomplete.
  285. Errors
  286. - Archive.AlreadyExists
  287. - Archive.DoesNotExist
  288. - Archive.IncompatibleFilesystemEncodingError
  289. - IntegrityError
  290. - NoManifestError
  291. - PlaceholderError
  292. Operations
  293. - cache.begin_transaction
  294. - cache.commit
  295. - cache.sync
  296. *info* is one string element, the name of the archive currently synced.
  297. - repository.compact_segments
  298. - repository.replay_segments
  299. - repository.check_segments
  300. - check.verify_data
  301. - extract
  302. *info* is one string element, the name of the path currently extracted.
  303. - extract.permissions
  304. - archive.delete