Compare commits
1262 Commits
80456791ac
...
8acb688693
Author | SHA1 | Date |
---|---|---|
Tim Stack | 8acb688693 | |
dependabot[bot] | a36c99cb73 | |
Tim Stack | cb55f588ec | |
Tim Stack | 33f0cc51b9 | |
Tim Stack | d36bb61f3e | |
Timothy Stack | 48798076c1 | |
Tim Stack | 8391de3ad6 | |
Tim Stack | 016bca01db | |
Tim Stack | f4e67df114 | |
Tim Stack | 057be8c66d | |
Tim Stack | faeaf477ab | |
Tim Stack | 468358a358 | |
Tim Stack | 3b1233be8f | |
Tim Stack | 9ff1daf032 | |
Tim Stack | 5a70e62003 | |
Tim Stack | 9eb734ef7e | |
Suresh Sundriyal | 071ec72586 | |
Suresh Sundriyal | e2cddf28b2 | |
Tim Stack | e135cf3334 | |
Tim Stack | 1a92701cb3 | |
Tim Stack | e1e6ca30eb | |
Fredrik Forsell | 59f3af535d | |
Fredrik Forsell | e310a18d7c | |
Tim Stack | f7b067db42 | |
Fredrik Forsell | 8f8be6fd20 | |
Fredrik Forséll | 91a03b7b86 | |
Fredrik Forséll | 6aba246bf3 | |
Tim Stack | e1f52dd6e2 | |
Tim Stack | b86d272c29 | |
Tim Stack | bddc6011ff | |
Tim Stack | 45b812d063 | |
Tim Stack | 5b34b3a604 | |
Tim Stack | 07c57dae08 | |
Tim Stack | d19eace826 | |
Tim Stack | 094b45f7ca | |
Timothy Stack | 1627698168 | |
Tim Stack | 2694a9855a | |
Tim Stack | 75fd859c6f | |
Tim Stack | d11b90bc6f | |
Tim Stack | 871ad1ad12 | |
Tim Stack | a31045a97b | |
Tim Stack | 0fd9845580 | |
Tim Stack | fd19759bf5 | |
Tim Stack | df0d3aed0c | |
Tim Stack | 7b84530e87 | |
dependabot[bot] | d7db3d6e9b | |
Tim Stack | 7f513b2d1f | |
Tim Stack | 93a53c4224 | |
Tim Stack | 59ec0b4794 | |
Tim Stack | 01d8ee0232 | |
Tim Stack | 4ecbee5162 | |
Tim Stack | 1249233ca1 | |
Tim Stack | cda76010d0 | |
Tim Stack | 2d03597487 | |
Tim Stack | d940d9d5eb | |
Tim Stack | 3f3e6dcbdc | |
Tim Stack | a437d9fcc9 | |
Tim Stack | d7e79b014d | |
Tim Stack | 26bcf0865d | |
Tim Stack | 5ae2c7dbe7 | |
Tobias Gruetzmacher | 0958a9b189 | |
Tim Stack | 20a06a2782 | |
Tim Stack | b7de0766c8 | |
Tim Stack | f1deeb5b74 | |
Tim Stack | e0ecbdff10 | |
Tim Stack | 9185518bda | |
Tim Stack | 5060b38f99 | |
Tim Stack | 1faa95df94 | |
Tim Stack | 81fc0dc47e | |
Tim Stack | b2abf94c2e | |
Tim Stack | d79c1f9235 | |
Tim Stack | 2ad379c454 | |
Tim Stack | 6016219d57 | |
Tim Stack | 502c3b5f20 | |
Tim Stack | c49e0787f3 | |
Tim Stack | 4445781038 | |
Tim Stack | 1effd99e5c | |
Tim Stack | b536043050 | |
Tim Stack | 116b40f28c | |
Tim Stack | bfa8ae2c42 | |
Tim Stack | 01fe042a84 | |
Tim Stack | 506d569b2f | |
Tim Stack | bf3fe7fc2c | |
Tim Stack | eb0bd4ac9a | |
Tim Stack | fadcea4403 | |
Tim Stack | 740b827901 | |
Tim Stack | 8613ad4d47 | |
Tim Stack | 2c5aaca254 | |
Tim Stack | f0b173b0af | |
Tim Stack | 38c10017ee | |
Tim Stack | eaa6e50a52 | |
Tim Stack | af5213a98a | |
Tim Stack | 132bd0adba | |
Tim Stack | 664f45f641 | |
Tim Stack | b2b300c7c8 | |
Tim Stack | 5a63ece31d | |
Tim Stack | ca4e61ba02 | |
Fulvio Scapin | 4b7c9ef54c | |
Tim Stack | aee33d6929 | |
Tim Stack | 66ec8e553e | |
Tim Stack | 6ca01cd934 | |
Randy Barlow | b16833392b | |
Tim Stack | 7309352c97 | |
Tim Stack | a813482a54 | |
Tim Stack | 2b1a8e4622 | |
Tim Stack | 7a3f4dbeaa | |
Tim Stack | f8e3417c62 | |
Tim Stack | 94fa27ead8 | |
Tim Stack | 679e9f0771 | |
Tim Stack | bea4fe5b3d | |
Tim Stack | ca51854e89 | |
Tim Stack | ac398dd441 | |
Tim Stack | e047386441 | |
Tim Stack | c9ec288853 | |
Tim Stack | 84d2f56189 | |
Tim Stack | 8d6780e089 | |
Tim Stack | eb403f540f | |
Tim Stack | 72d171ae4b | |
Tim Stack | 8e33c599f1 | |
Tim Stack | a6cbed6162 | |
Tim Stack | d8ae7053e6 | |
Fulvio Scapin | cad1d80be3 | |
Tim Stack | 84536d804c | |
Tim Stack | cc598e3ae6 | |
Tim Stack | f0d9ab5f40 | |
Tim Stack | c69b398944 | |
Tim Stack | 1f24ab3074 | |
Tim Stack | 7a1ade581a | |
Tim Stack | b5cb38d454 | |
Tim Stack | ff91cfc3a0 | |
Tim Stack | 915f583ab0 | |
Tim Stack | fa0050be84 | |
Tim Stack | 311798e1f8 | |
Tim Stack | cebc867c6b | |
Tim Stack | e90fe620c9 | |
Timothy Stack | 220317eb16 | |
Tim Stack | 4b307b5b4f | |
Tim Stack | 5e6ac10663 | |
Tim Stack | 87791ec94b | |
Tim Stack | fd956c66d3 | |
Tim Stack | d01db38d51 | |
Tim Stack | 5751fe89c4 | |
Tim Stack | 0d1304e8ec | |
Tim Stack | ebaeb43fcb | |
Tim Stack | a2c35140ba | |
Tim Stack | 23ab1abd73 | |
Tim Stack | 7310f9dcec | |
Tim Stack | 412a3c2a70 | |
Tim Stack | 53c9c5cb51 | |
Tim Stack | ad1897ba15 | |
Tim Stack | 5abd483029 | |
Tim Stack | 9c8cc04a99 | |
Tim Stack | 8e734eaf07 | |
Tim Stack | af75f7bd80 | |
Tim Stack | ceb1779f9f | |
Tim Stack | b70fa47b6d | |
Tim Stack | 31bd108bf2 | |
Tim Stack | c50b0a20a8 | |
Tim Stack | 839dfe0c1b | |
Tim Stack | 74c2237296 | |
Tim Stack | 001f26d066 | |
Tim Stack | 072fad4173 | |
Tim Stack | 35a8e99c07 | |
Tim Stack | 88d9002a5d | |
Tim Stack | d020168860 | |
Tim Stack | a1de8f1fc1 | |
Tim Stack | 7ef5cf6ba3 | |
Tim Stack | 0603b1e756 | |
Tim Stack | 13f161d21e | |
Tim Stack | c824b64840 | |
Tim Stack | 270d44c6b4 | |
Tim Stack | f73e71cf30 | |
Tim Stack | 1e63cfc5ae | |
Tim Stack | 1c440ecb6f | |
Tim Stack | d9e699fd09 | |
Tim Stack | 061e3690de | |
Tim Stack | ca7efa822f | |
Tim Stack | ebe2e0d8e6 | |
Tim Stack | 1fd274ce24 | |
Tim Stack | c52615c424 | |
Tim Stack | 3df07139b3 | |
Tim Stack | 4e74491e84 | |
Tim Stack | deb0e21554 | |
Tim Stack | bbedca5940 | |
Tim Stack | 01405ffbd6 | |
Tim Stack | 1832303bde | |
Tim Stack | b829b6ddde | |
Tim Stack | 8941f28c3e | |
Tim Stack | c5d11f36e1 | |
Tim Stack | 3ade11a449 | |
Tim Stack | 7077495389 | |
Tim Stack | 4e0dab843a | |
Tim Stack | 1c793f6f28 | |
Tim Stack | c5b8bd0ba4 | |
Tim Stack | a4fadb56f6 | |
Tim Stack | 7c3df44fc4 | |
Tim Stack | 056754a926 | |
Tim Stack | c6d7206a1e | |
Tim Stack | ab3f01bbf5 | |
Tim Stack | 5259da4f4f | |
Tim Stack | bdacaa6f86 | |
Tim Stack | 010198531b | |
Tim Stack | 7b32ea9d39 | |
Tim Stack | df082eaf16 | |
Tim Stack | 363eb35da3 | |
Tim Stack | 3cafcf3c77 | |
Tim Stack | 40037b0fd1 | |
Tim Stack | d22727242a | |
Tim Stack | 9675eb5902 | |
Tim Stack | 1ae1600f7b | |
Tim Stack | c17046b2fa | |
Tim Stack | e2e491ec41 | |
Tim Stack | 3b9bc57ab0 | |
Tim Stack | c9c573d2ad | |
Tim Stack | 94aab91d38 | |
Tim Stack | 1f8e2bd46c | |
Tim Stack | be862e0eab | |
Tim Stack | f234b37fe0 | |
Tim Stack | 9c03938ff3 | |
Tim Stack | 390bc132e2 | |
Timothy Stack | 8ef581177c | |
Timothy Stack | 0f2d38df50 | |
Timothy Stack | a459370bd8 | |
Timothy Stack | 16d39f3fd9 | |
Timothy Stack | 66853a70ca | |
Timothy Stack | ff44e37f7e | |
Timothy Stack | a5a02d6243 | |
Timothy Stack | 20165a85e7 | |
Timothy Stack | f8aac1d52e | |
Timothy Stack | 7ed2437a01 | |
Timothy Stack | b3ee092dc5 | |
Timothy Stack | 317f2d32cf | |
Timothy Stack | e8f0b1e6b8 | |
Timothy Stack | 935290b521 | |
Timothy Stack | 41754a8ec1 | |
Timothy Stack | a04dc2a327 | |
Timothy Stack | 773cc3e049 | |
Timothy Stack | 6712a33163 | |
Timothy Stack | 1abc77e129 | |
Timothy Stack | 5ea55afd74 | |
Timothy Stack | 80bddbd2e7 | |
Timothy Stack | 0f9c519061 | |
Timothy Stack | 76991744e4 | |
Timothy Stack | d4f0cbd8ce | |
Timothy Stack | d98b5a5a88 | |
Timothy Stack | 3ac5ce1e51 | |
Timothy Stack | 981a3d6b70 | |
Timothy Stack | 0b99c0b9a4 | |
Timothy Stack | dabd93a63a | |
Timothy Stack | 6224ed2ce3 | |
Timothy Stack | 7b83b87e57 | |
Timothy Stack | fcb4794e87 | |
Timothy Stack | 45270505e3 | |
Timothy Stack | f5cc4b298f | |
Timothy Stack | d1521496cc | |
Timothy Stack | 4c20b0039c | |
Timothy Stack | dde6d88430 | |
Timothy Stack | e669f6ca55 | |
Timothy Stack | 3c54f20fce | |
Timothy Stack | 3b9235b6e6 | |
Timothy Stack | 6393990b91 | |
Timothy Stack | a3f5c3239e | |
Timothy Stack | 39763b2d31 | |
Timothy Stack | 880fe6a68a | |
Timothy Stack | f3934c742d | |
Timothy Stack | 8b3b8a6e3c | |
Timothy Stack | 01031a9fa3 | |
Timothy Stack | 7db3c7d3cf | |
Timothy Stack | 36e9433891 | |
Timothy Stack | 09bd5396b2 | |
Timothy Stack | ef7c7fa9b4 | |
Timothy Stack | a687de1690 | |
Timothy Stack | ea16ee630b | |
Timothy Stack | dae3f6b7bc | |
Timothy Stack | c27ee7fdd5 | |
Timothy Stack | 262c993a31 | |
Timothy Stack | a3e1fd27b8 | |
Timothy Stack | 7fe91d6186 | |
Timothy Stack | d6c9b0036a | |
Timothy Stack | 812fa08055 | |
Timothy Stack | 13910aff7a | |
Timothy Stack | 635dd996a9 | |
Timothy Stack | 20cb489ce3 | |
Timothy Stack | 52fe2db376 | |
Timothy Stack | cec6c3a225 | |
Timothy Stack | 2351438e4c | |
Timothy Stack | 72c1c48e23 | |
Timothy Stack | d5b06fca5f | |
Timothy Stack | bd1b90a101 | |
Timothy Stack | 09ee65e917 | |
Timothy Stack | f6fa834aa6 | |
Timothy Stack | 5fc9917a4b | |
Timothy Stack | ce7f974598 | |
Timothy Stack | c666a669fe | |
Timothy Stack | 717c039100 | |
Timothy Stack | 689793d39f | |
Timothy Stack | 2a9f0bcda8 | |
Timothy Stack | f9f797fc9d | |
Timothy Stack | 906494ebfa | |
Timothy Stack | a3b9314ff7 | |
Timothy Stack | 464cda8b82 | |
Timothy Stack | 041cc2c551 | |
Timothy Stack | c24be236a3 | |
Timothy Stack | 9d590836f3 | |
Timothy Stack | c0f4254f1c | |
Timothy Stack | 64e7b78c6b | |
Timothy Stack | 6c6d1cbf41 | |
Timothy Stack | db754068c8 | |
Timothy Stack | 84ec014a8d | |
Timothy Stack | 7eb4d1b6e6 | |
Timothy Stack | f3e6048b3c | |
Timothy Stack | e03d216b8b | |
Timothy Stack | bcc7436f66 | |
Timothy Stack | 64bee48fb0 | |
Timothy Stack | bc467aacf2 | |
Timothy Stack | 7d2258764c | |
Timothy Stack | 1891ceb7b5 | |
Timothy Stack | d9ae810dd6 | |
Timothy Stack | 56f6b801d2 | |
Timothy Stack | 6c52760cc9 | |
Timothy Stack | 1ea385ea3b | |
Timothy Stack | 9dbbec832c | |
Timothy Stack | d54f21d7a5 | |
Timothy Stack | eeddc318ff | |
Timothy Stack | 0b6de5ae31 | |
Timothy Stack | 60251dda84 | |
Timothy Stack | ef8c641e59 | |
Timothy Stack | 3b54260ea4 | |
Timothy Stack | a442418b18 | |
Timothy Stack | 10a7152ca6 | |
Timothy Stack | b74dfbfb03 | |
Timothy Stack | 54806f7913 | |
Timothy Stack | d7162f6366 | |
Timothy Stack | c9724e1eb2 | |
Timothy Stack | adf8f77e30 | |
Timothy Stack | 023c9568d8 | |
Timothy Stack | f01564fea4 | |
Timothy Stack | dfaeee7f44 | |
Timothy Stack | 24a56042d0 | |
Timothy Stack | 1dade3d66e | |
Timothy Stack | 6105db3c32 | |
Timothy Stack | 6b59b03750 | |
Timothy Stack | f389005d40 | |
Timothy Stack | ae0760045e | |
Timothy Stack | 4dccb7424c | |
Timothy Stack | 2e20195b99 | |
Timothy Stack | 2bc258e621 | |
Timothy Stack | 31a670ce27 | |
Timothy Stack | 0c7f6145c9 | |
Timothy Stack | 5e6985d8a4 | |
Timothy Stack | b2e4e59a40 | |
Timothy Stack | 45262b80c4 | |
Timothy Stack | dd93250648 | |
Timothy Stack | f03f9e704f | |
Timothy Stack | 2c4b1d3886 | |
Timothy Stack | 64d5ae4ad4 | |
Timothy Stack | 7cc55734a8 | |
Timothy Stack | d161f5cdac | |
Timothy Stack | 6e26e90096 | |
Timothy Stack | ea362a5866 | |
Timothy Stack | 0c54d19fc0 | |
Timothy Stack | c17f40f7ab | |
Timothy Stack | 6f8cafaf84 | |
Timothy Stack | 182da31213 | |
Timothy Stack | f2968a7032 | |
Timothy Stack | 45b9745cf2 | |
Timothy Stack | a27198e8ca | |
Tim Stack | 69b5cb1d58 | |
Timothy Stack | 6251aa066c | |
Timothy Stack | c43367491c | |
Timothy Stack | b69b3e4ec4 | |
Timothy Stack | d378398b33 | |
Timothy Stack | 4439c9f3ce | |
Timothy Stack | 0785a432fa | |
Pedro Pombeiro | 880ae7fc57 | |
Timothy Stack | 7652c58248 | |
Timothy Stack | c125211a7e | |
Timothy Stack | 1019714409 | |
Timothy Stack | 292724d7ad | |
Timothy Stack | 5eaf1c4332 | |
Timothy Stack | c8799b1c99 | |
tstack | 28957de012 | |
Timothy Stack | d82140de52 | |
Timothy Stack | 531c35158c | |
Timothy Stack | 99c1688c2e | |
Timothy Stack | ffd364ec12 | |
Timothy Stack | 81e63784e7 | |
tstack | cfa6f35c44 | |
Timothy Stack | b856cd9657 | |
Timothy Stack | 98ca668a03 | |
Timothy Stack | 6fff9d60f5 | |
Timothy Stack | eb42ef6e77 | |
Timothy Stack | 8b3bb9312e | |
Timothy Stack | 516a20b94a | |
Timothy Stack | 66ef5fdae1 | |
Timothy Stack | d0ba84d9be | |
Timothy Stack | a0ee4427a6 | |
Timothy Stack | 4564e162d0 | |
Tim Stack | f2256c7aab | |
Pedro Pombeiro | ca3b4b6c8c | |
Pedro Pombeiro | 5028f84b59 | |
Pedro Pombeiro | 16f5886cb1 | |
Timothy Stack | 0e23dcf4b5 | |
Timothy Stack | 87beb6dd78 | |
Tim Stack | d43576e41a | |
Pedro Pombeiro | 894c36dac4 | |
Tim Stack | 30c603c1c8 | |
Peter Schiffer | b8a31ae9b4 | |
Tim Stack | 4d62826cae | |
Cristian Chiru | 146a2ad857 | |
Tim Stack | c254c7ebc6 | |
Cristian Chiru | 084b88b6f4 | |
Cristian Chiru | b23e0ad508 | |
Cristian Chiru | e2fe64e536 | |
Cristian Chiru | 092af9b694 | |
Tim Stack | b2c7018d2d | |
solsTiCe d'Hiver | 62901ac89d | |
Tim Stack | f02a8e2fe9 | |
Timothy Stack | 43df8f75a2 | |
Timothy Stack | 8bb034eeeb | |
Timothy Stack | c52240a25d | |
Timothy Stack | f74214b9b6 | |
Timothy Stack | b8945232f7 | |
Tim Stack | b9b4d24933 | |
Timothy Stack | f33a9a580b | |
eladeyal-intel | 0f25ec6c3b | |
Timothy Stack | fa3c7048c9 | |
Timothy Stack | 561262c2f9 | |
Timothy Stack | 3d31b2b723 | |
Timothy Stack | 7627c41802 | |
Timothy Stack | 19fd336e9a | |
Timothy Stack | 782878b05c | |
Timothy Stack | 6e6487935a | |
Timothy Stack | 008b1c827b | |
Timothy Stack | 5089347e82 | |
Tim Stack | a9278b400d | |
Tim Stack | 1c8e0f2ef3 | |
Timothy Stack | 7c51c3264b | |
Tim Stack | 1bc6b91dd7 | |
Timothy Stack | d71fd7bff2 | |
Timothy Stack | 2cac26cc00 | |
Timothy Stack | 3c36869711 | |
Timothy Stack | b3b8ed7f07 | |
Timothy Stack | d228c5a9e1 | |
Timothy Stack | dc0b7ff631 | |
Timothy Stack | b884f732f2 | |
Timothy Stack | 954e368974 | |
Timothy Stack | 4ba892677e | |
Timothy Stack | 644c61c82a | |
Timothy Stack | cb3e587cb4 | |
Tim Stack | f4d9e51f4c | |
Timothy Stack | 68d7d64948 | |
Timothy Stack | 1c5567157f | |
Timothy Stack | 458b959a13 | |
Timothy Stack | 272de832d5 | |
Timothy Stack | 3c5b86b5ed | |
Timothy Stack | 2edc3c8382 | |
Timothy Stack | 806e3d934e | |
Timothy Stack | 90b8e85e62 | |
Timothy Stack | 90b513499c | |
Timothy Stack | b2f11ac27f | |
Timothy Stack | d6535c40f6 | |
Timothy Stack | ecb4084b37 | |
Randy Barlow | 85515b2c19 | |
Timothy Stack | 6761e2d7df | |
tstack | 2315fc8871 | |
Timothy Stack | c317008463 | |
tstack | fa8dc6214f | |
Timothy Stack | 2f9f72762f | |
tstack | f5f41ffad9 | |
Timothy Stack | 4fc6e60d10 | |
Timothy Stack | d1fb112223 | |
Timothy Stack | 88029aa847 | |
Timothy Stack | d239bb4594 | |
Timothy Stack | 4d16be7b6e | |
Timothy Stack | 8394453c8d | |
Timothy Stack | 98bc71914b | |
tstack | cddad0ac92 | |
Timothy Stack | 47964ac852 | |
tstack | 90cae9d59b | |
Timothy Stack | e8f3468801 | |
Timothy Stack | a50c806bd9 | |
tstack | ca98425e10 | |
Timothy Stack | a125e49415 | |
Timothy Stack | aae83a6a10 | |
Timothy Stack | aa30526a54 | |
Timothy Stack | 107199cb7c | |
Timothy Stack | f6e245c04a | |
Timothy Stack | 7252e5fc0f | |
Timothy Stack | d4d0a6165f | |
Timothy Stack | 4bee577b26 | |
Timothy Stack | b3a4eadbe2 | |
Timothy Stack | dd527cf6d4 | |
Timothy Stack | c308a3b17a | |
Timothy Stack | b6b0578027 | |
Timothy Stack | 86e84e1dab | |
Timothy Stack | 1e1abcc97e | |
Timothy Stack | db7173caec | |
Timothy Stack | 312a97bca7 | |
Timothy Stack | 0de76b29c8 | |
Tim Stack | 869b10c3fc | |
Tim Stack | fbdcca97e1 | |
Timothy Stack | 2df39916f9 | |
Timothy Stack | 42d2aa063a | |
Timothy Stack | c462830be1 | |
Timothy Stack | aa9947fbb0 | |
Timothy Stack | 2000513135 | |
Tim Stack | 49576d8450 | |
Tim Stack | 0fcda9adec | |
Timothy Stack | ec4e36b10c | |
Timothy Stack | 67557c829a | |
Timothy Stack | a7edb40cf7 | |
Timothy Stack | c13e1f3a00 | |
Timothy Stack | 804056c1c3 | |
Timothy Stack | 7eb1d17bef | |
Timothy Stack | 1df74411c2 | |
Timothy Stack | 03ce38b09f | |
Timothy Stack | 426e70b99f | |
Tim Stack | ab9cedeb7d | |
Timothy Stack | 87ae18238b | |
Tim Stack | 283cdf7ca6 | |
a1346054 | e68be8f447 | |
a1346054 | f30ed34a22 | |
a1346054 | 65791b79ef | |
a1346054 | a362683dc8 | |
a1346054 | 4406feba3b | |
a1346054 | b402e79e9e | |
a1346054 | 03fd7cc52d | |
a1346054 | 1bd81ec630 | |
a1346054 | 285e171b54 | |
Timothy Stack | ef276bce72 | |
Timothy Stack | 65acae6f0e | |
Timothy Stack | 211f10535c | |
Timothy Stack | 97530070c9 | |
Timothy Stack | c9d22e7941 | |
Timothy Stack | 383bf71f26 | |
Timothy Stack | e33fe1a85b | |
Timothy Stack | ce8397b5cf | |
Timothy Stack | b6cb1e6dda | |
Timothy Stack | 981bced044 | |
Timothy Stack | 7a66283bf2 | |
Tim Stack | 581ab446ba | |
dependabot[bot] | 943f243f3a | |
Timothy Stack | 65a7bd7bd6 | |
Timothy Stack | 5f1dbac193 | |
Timothy Stack | 6c6a5c11cc | |
Timothy Stack | ea34d7cd5f | |
Timothy Stack | b184272edb | |
Timothy Stack | 4a11b737df | |
Timothy Stack | 23cb718d65 | |
Timothy Stack | 4445a54847 | |
Timothy Stack | 872b9411aa | |
Timothy Stack | 9fffa728de | |
Timothy Stack | d42006d0a9 | |
Timothy Stack | c13e78358e | |
Timothy Stack | 04c4f8a779 | |
Timothy Stack | f5b866844d | |
Tim Stack | bb35ac1471 | |
Timothy Stack | dbcfdda363 | |
Timothy Stack | aa7ac37cdc | |
Timothy Stack | b77367a3d3 | |
Timothy Stack | 02167e2caf | |
Timothy Stack | 08ba6c0914 | |
tstack | 9a8703ae7c | |
Timothy Stack | 9138251355 | |
Timothy Stack | 22ad9f23a9 | |
Timothy Stack | 3041dca1ed | |
Timothy Stack | 488397b41c | |
Timothy Stack | e07581c742 | |
Timothy Stack | a9aac1f36b | |
Tim Stack | f571feaedc | |
Timothy Stack | b9a8ac7141 | |
Timothy Stack | de86f4cce0 | |
Timothy Stack | 1d6ac461ba | |
Timothy Stack | 4b6fb5ff18 | |
tstack | 0c5dc3840f | |
Timothy Stack | 131edc2823 | |
tstack | 5cb6d5ea1b | |
Timothy Stack | b4e9384ac5 | |
Timothy Stack | 1dcf92e982 | |
tstack | e4868d5ae2 | |
Timothy Stack | b38bd6e2fe | |
tstack | 796a02aa15 | |
Timothy Stack | 528f7be9d2 | |
Timothy Stack | 9c6715fa18 | |
Timothy Stack | b1adcdef36 | |
Timothy Stack | 9ec58bf9af | |
Timothy Stack | bc76a3ee90 | |
Timothy Stack | e1ee89fc39 | |
Timothy Stack | a760a4240f | |
Timothy Stack | ace63947df | |
Timothy Stack | b2d296b5d3 | |
Timothy Stack | 408a2ea38e | |
Timothy Stack | 3cc22dc88c | |
Timothy Stack | 75ead0eb60 | |
Timothy Stack | d5d44e63b3 | |
Timothy Stack | 71d1ab1a96 | |
Timothy Stack | 516d13d772 | |
Timothy Stack | 27bc9cf117 | |
Timothy Stack | 76ce111d48 | |
Timothy Stack | d3d527d290 | |
Timothy Stack | b5406f2cee | |
Timothy Stack | 75a01d0f50 | |
Timothy Stack | ed93eb71c0 | |
Timothy Stack | f5ee4306db | |
Timothy Stack | a2e36921d5 | |
Timothy Stack | a87c420070 | |
Timothy Stack | 8f7b08c9c5 | |
Timothy Stack | a6a411834e | |
Timothy Stack | 912f7939d0 | |
Timothy Stack | 9c417afb2d | |
Timothy Stack | 96a00f2085 | |
Timothy Stack | 326fbae163 | |
Timothy Stack | d85cae933e | |
Timothy Stack | 46bafa1dea | |
Timothy Stack | c0ea709dd4 | |
Timothy Stack | 8589dd253a | |
Timothy Stack | 0dca44f487 | |
Timothy Stack | 4dfd8b2c97 | |
tstack | 4638370f7c | |
Timothy Stack | b80e322162 | |
Timothy Stack | bce7192bee | |
tstack | d4fc61cbe8 | |
Timothy Stack | 1737964df6 | |
tstack | 5ab5d9a4f4 | |
Timothy Stack | abbc935c37 | |
Timothy Stack | 5ceb85838d | |
Timothy Stack | a8e7a69c49 | |
Timothy Stack | 108dc1b77a | |
Timothy Stack | db5fd8e0ec | |
Timothy Stack | 8f03a441d3 | |
Timothy Stack | 9231e812d7 | |
Timothy Stack | 399cf83fc5 | |
Timothy Stack | edfd835866 | |
Timothy Stack | 8582b56c75 | |
tstack | 529088f911 | |
Timothy Stack | d09cffd9b4 | |
Timothy Stack | 857ba5c8e1 | |
Timothy Stack | 33bfc873b1 | |
Timothy Stack | 5607b1b08e | |
Timothy Stack | db1fac9def | |
Timothy Stack | 93b33929a3 | |
Timothy Stack | 09fdfa1034 | |
Timothy Stack | b78c914d6f | |
Timothy Stack | 9a91cdffbb | |
Timothy Stack | 12cf00f4dc | |
Timothy Stack | 6ebd9f16a2 | |
Timothy Stack | c3dc668b69 | |
Timothy Stack | be51a4e3de | |
Timothy Stack | e13816a8e3 | |
Timothy Stack | b64342ca47 | |
Timothy Stack | d2b5690e0c | |
Timothy Stack | 98677eb09a | |
Timothy Stack | 1849609e07 | |
Timothy Stack | 681f771bb7 | |
Timothy Stack | 0dbe5f0f94 | |
Timothy Stack | ab671d5834 | |
Timothy Stack | 0a0e355696 | |
Timothy Stack | 6ff3badc62 | |
Timothy Stack | 224eb6fe55 | |
Timothy Stack | 5ea22b1c0c | |
Timothy Stack | a37a859c11 | |
Timothy Stack | 7f4c9868e0 | |
Timothy Stack | 1525a7ce98 | |
Timothy Stack | 65dd0bfeb8 | |
Timothy Stack | e88e37184f | |
Timothy Stack | ca5ec33241 | |
Tim Stack | 5aaea49b4b | |
Timothy Stack | c2f0919ed3 | |
Timothy Stack | ad6f469378 | |
Timothy Stack | 04676d75b7 | |
Timothy Stack | f050c7b0a7 | |
Nicolas Bock | 125c872849 | |
Tim Stack | 5742e5eb09 | |
Nicolas Bock | 97e8e6c87b | |
Timothy Stack | 94498878c8 | |
Timothy Stack | 2748171d2c | |
Timothy Stack | 26751a7e2e | |
Timothy Stack | 380969ee8d | |
Timothy Stack | 444e7e3289 | |
Timothy Stack | cc1e79d1cc | |
Timothy Stack | 0fd7f31222 | |
Timothy Stack | 3741985ee3 | |
Timothy Stack | 70c07da5c5 | |
Timothy Stack | b7817d4bb9 | |
Timothy Stack | d31aa845f5 | |
Timothy Stack | d15c1103cf | |
Timothy Stack | 73a4df61e3 | |
Timothy Stack | 0658b9ef57 | |
Timothy Stack | d183247a31 | |
Timothy Stack | 32ddc76624 | |
Timothy Stack | 30b4067e43 | |
Timothy Stack | e593bde875 | |
Timothy Stack | f4c5f42e87 | |
Timothy Stack | ef916a3fca | |
Timothy Stack | 32bfd76cdb | |
Timothy Stack | 2e4106b80a | |
Timothy Stack | bfa1877f4e | |
Timothy Stack | 66eb3c76e6 | |
Timothy Stack | def50ee6cf | |
Timothy Stack | 94b3c0d467 | |
Timothy Stack | c0ed59e61e | |
Timothy Stack | 6f4791ec35 | |
Timothy Stack | 92fd72aa97 | |
Timothy Stack | 9b328ad5c7 | |
Timothy Stack | dd9465cd10 | |
Timothy Stack | 92e20ffd51 | |
Timothy Stack | 0b3819d16a | |
Timothy Stack | 4f4d90a65d | |
Timothy Stack | 5d4f08b1b4 | |
Timothy Stack | 1b16376076 | |
Timothy Stack | 3c10b1f34b | |
Timothy Stack | 749fdacfa8 | |
Timothy Stack | 7b0e1c4f54 | |
Timothy Stack | 6749d6b53c | |
Timothy Stack | 72275aa968 | |
Timothy Stack | def2fe4bcb | |
Timothy Stack | f6128240ab | |
Timothy Stack | 68759ada2d | |
Timothy Stack | c177a321fb | |
Timothy Stack | 5af3664bc1 | |
Timothy Stack | d45d7d6c58 | |
Timothy Stack | 4d2691fa99 | |
Timothy Stack | 9575f9c7d7 | |
Tim Stack | bbba9ff732 | |
Timothy Stack | c1c0036a5c | |
Timothy Stack | 8fa4cef1b5 | |
Timothy Stack | 864168ec7f | |
Tim Stack | 2010dabfc2 | |
Timothy Stack | f5c72736cb | |
Timothy Stack | 0f238f7972 | |
Timothy Stack | 43bb384199 | |
Timothy Stack | f5e88b7158 | |
Timothy Stack | fd40b55e0a | |
Tim Stack | 995fd80751 | |
Timothy Stack | 2c00331040 | |
Timothy Stack | a4368223ea | |
Timothy Stack | 351ad7a8fc | |
Timothy Stack | 6deb7032a6 | |
Tim Stack | 0269aa1d47 | |
Timothy Stack | 2750d23b07 | |
Timothy Stack | 58f1c9df1c | |
Timothy Stack | 0a701394fe | |
Timothy Stack | 37523fe7d0 | |
Timothy Stack | 3b5a5b448a | |
Timothy Stack | 7e6b3dcc23 | |
Timothy Stack | b847ae7164 | |
Timothy Stack | 7821d07b7c | |
Timothy Stack | 66747ef627 | |
Timothy Stack | 85b9329332 | |
Timothy Stack | f35c0c397e | |
Timothy Stack | e5a216e717 | |
Timothy Stack | caa5cc9003 | |
Timothy Stack | 5c02766485 | |
Timothy Stack | 47fb48eaf3 | |
Timothy Stack | 0f81bebcb7 | |
Timothy Stack | 7778042847 | |
Timothy Stack | 805e7abaaa | |
Timothy Stack | c5ab97352d | |
Timothy Stack | af9cea19e2 | |
Timothy Stack | b85f9fd1d4 | |
Timothy Stack | f36954741d | |
Timothy Stack | 83345f85c1 | |
Timothy Stack | a120bf2c0c | |
Timothy Stack | efea67e61c | |
Timothy Stack | 5c203a2648 | |
Timothy Stack | b3e4b5d68d | |
Timothy Stack | 3566e122ae | |
Timothy Stack | 00890970cd | |
Timothy Stack | 681618a513 | |
Timothy Stack | d5fd3410d7 | |
Timothy Stack | 28cd4f9ddf | |
Timothy Stack | 6c864696da | |
Timothy Stack | fa7f8cf3a7 | |
Timothy Stack | 49ebde5953 | |
Timothy Stack | 2b9f4c6d3a | |
Timothy Stack | b5af750256 | |
Timothy Stack | 099b32b393 | |
Timothy Stack | f17d838be1 | |
Timothy Stack | 215c08f632 | |
Timothy Stack | 50b63559ce | |
Timothy Stack | 775d2443a6 | |
Timothy Stack | 310c67c53e | |
Timothy Stack | bc48911e42 | |
Timothy Stack | eea5220191 | |
Timothy Stack | cac1175973 | |
Timothy Stack | 8633afdff3 | |
Timothy Stack | 92a31534cf | |
Timothy Stack | e5f37ee3ff | |
Timothy Stack | a871ad5dbc | |
Timothy Stack | 076d730fa2 | |
Timothy Stack | 56bee6f4c9 | |
Timothy Stack | ae422bb37e | |
Timothy Stack | a768f0146f | |
Timothy Stack | 8851c4492f | |
Timothy Stack | 678be94d75 | |
Timothy Stack | be71834733 | |
Timothy Stack | 5599c9cc80 | |
Timothy Stack | 6be36eda19 | |
Timothy Stack | 8235f9af5d | |
Timothy Stack | 4d936f7bba | |
Timothy Stack | 853ef11435 | |
Timothy Stack | 7f80d47ae4 | |
Timothy Stack | cc072d29ea | |
Timothy Stack | 60dde499ac | |
Timothy Stack | 1cefe583fa | |
Timothy Stack | 2de57d242d | |
Timothy Stack | 6d8a9f2121 | |
Timothy Stack | 2996a90afa | |
Tim Stack | 787b33f45c | |
Timothy Stack | 1d17ac7f29 | |
Timothy Stack | 63c31838eb | |
Tim Stack | f5f1626b07 | |
Timothy Stack | 9a073e80e7 | |
Timothy Stack | 7476dd5bb9 | |
Timothy Stack | bfa2c7f38c | |
Tim Stack | a13ad5b7c2 | |
Timothy Stack | 4ca6fd7bfd | |
eladeyal-intel | f41d5cc414 | |
Timothy Stack | 9ed3a80326 | |
Timothy Stack | 4ff2b710d5 | |
Tim Stack | a9a08d3315 | |
Timothy Stack | 941504a4cb | |
Phil Hord | 7ad40f7263 | |
Phil Hord | f10a303f54 | |
Timothy Stack | 3a11140b27 | |
Timothy Stack | e6df0fba0a | |
Timothy Stack | e04d04c1a9 | |
Timothy Stack | 6b0b3a65dd | |
Timothy Stack | 127fb20b28 | |
Timothy Stack | 04da95eb95 | |
Timothy Stack | 9c1f2ca4fa | |
Timothy Stack | 159608cdcc | |
Timothy Stack | 730233e356 | |
Timothy Stack | 9d6941c89d | |
Timothy Stack | 8a2fb80888 | |
Timothy Stack | 267e32d479 | |
Timothy Stack | e3f28eaa43 | |
Tim Stack | 560c2d4ec3 | |
Timothy Stack | 030c73e76b | |
Timothy Stack | 642fce3548 | |
Timothy Stack | 836fc83203 | |
Timothy Stack | a0986bf271 | |
Timothy Stack | 623da1fe33 | |
Timothy Stack | 5f1ffb24a8 | |
Timothy Stack | 32f112b8de | |
Timothy Stack | 8494aefd50 | |
Timothy Stack | 86d515b4bc | |
Timothy Stack | d773fe0b9a | |
Timothy Stack | 6b630f55dd | |
Timothy Stack | 19e0624ab6 | |
Timothy Stack | 21f127cb56 | |
Timothy Stack | b924395ed2 | |
Timothy Stack | 0d31323a18 | |
Timothy Stack | 33621e1936 | |
Timothy Stack | 3a2a1e0dda | |
Timothy Stack | 08739e4235 | |
Timothy Stack | 927aecc437 | |
Timothy Stack | 3c0dbf3324 | |
Timothy Stack | 900834f7c8 | |
Timothy Stack | 49a6f6df11 | |
Timothy Stack | 22a7e4deeb | |
Timothy Stack | 22c2e95df0 | |
Timothy Stack | 6d0054d3b6 | |
Timothy Stack | 2aad7985a6 | |
Tim Stack | ba26c79508 | |
Nicolas Bock | 5be45cf397 | |
Timothy Stack | d3fa76e8e9 | |
Timothy Stack | a29d3bc745 | |
Timothy Stack | 0e9962f187 | |
Tim Stack | 8dbb60215e | |
Timothy Stack | 9a431f5354 | |
Timothy Stack | 1e1d12bd0b | |
Timothy Stack | fa9a66152f | |
Timothy Stack | 8e629b166a | |
Timothy Stack | 6fe2f552d5 | |
Timothy Stack | d6055d178b | |
Timothy Stack | 5bffcb4c3e | |
Timothy Stack | d1a84b3606 | |
Timothy Stack | 51d1204a96 | |
Timothy Stack | 0765c07010 | |
Timothy Stack | b1a0227cbd | |
Timothy Stack | 9d87cfa2f0 | |
Timothy Stack | cb7a8904c1 | |
Timothy Stack | 9eee6b2b64 | |
Timothy Stack | f192cb7c3e | |
Timothy Stack | db8a3c4d38 | |
Timothy Stack | 21e78670e2 | |
Timothy Stack | 00dcd86f79 | |
Timothy Stack | 78d5954fd7 | |
Timothy Stack | 5c73ce0a85 | |
Timothy Stack | e4ea9ca584 | |
Timothy Stack | 563fa94d39 | |
Timothy Stack | 8433a67c68 | |
Timothy Stack | 9bfe1f8319 | |
Timothy Stack | df3df8369c | |
Timothy Stack | 5e42b4cb8a | |
Timothy Stack | 0dff822ade | |
Timothy Stack | 56866d8a33 | |
Timothy Stack | 8b38bb0970 | |
Timothy Stack | c22c78220c | |
Timothy Stack | 7b77a612c2 | |
Timothy Stack | dfd18a4be5 | |
Timothy Stack | 4b7244d06c | |
Timothy Stack | a63cf003a0 | |
Timothy Stack | 3b0168025d | |
Timothy Stack | 579e4274f9 | |
Timothy Stack | 9f524136bd | |
Timothy Stack | e7f5bf3a6a | |
Timothy Stack | 59665368ee | |
Tim Stack | 4b30dffd6b | |
Phil Hord | 1d127053e9 | |
Timothy Stack | 2a7db9b257 | |
Timothy Stack | d8a083f0fe | |
Timothy Stack | b44b6d24cf | |
Timothy Stack | 276f71423e | |
Tim Stack | cc6ae5ee2e | |
Tim Stack | 7c215f09c6 | |
Suresh Sundriyal | cac46e9848 | |
Tim Stack | e539aca4ea | |
Suresh Sundriyal | 3a9967cbf5 | |
Suresh Sundriyal | cc6f0a06dd | |
Timothy Stack | 0e1eb418c8 | |
Timothy Stack | 8f0c918bb3 | |
Timothy Stack | 5e01902c60 | |
Timothy Stack | 2cd0ee7200 | |
Timothy Stack | 15f38ce6ba | |
Timothy Stack | 74bfa21050 | |
Timothy Stack | 65c991919b | |
Timothy Stack | 7763d2db7a | |
Timothy Stack | 6ec90c521b | |
Timothy Stack | e04d49bc98 | |
Timothy Stack | ec920a771f | |
Timothy Stack | 0b1b57debb | |
Timothy Stack | 267ca92025 | |
Timothy Stack | c3646be987 | |
Timothy Stack | a4e6328ff7 | |
Tim Stack | 0bfb11fcc8 | |
Timothy Stack | cb58f3d1ae | |
Tim Stack | 4434e9f2aa | |
Suresh Sundriyal | f8e990cf76 | |
Tim Stack | 65b999c5ca | |
Timothy Stack | dd2fb1d0c5 | |
Suresh Sundriyal | 8b2bcca752 | |
Timothy Stack | 47c8a32481 | |
Timothy Stack | 82c7b236ee | |
Timothy Stack | b1e89be4c3 | |
Timothy Stack | 6cbc888786 | |
Timothy Stack | b2d5a41762 | |
Tim Stack | 20c6ec3166 | |
Suresh Sundriyal | 091f3c04b4 | |
Timothy Stack | f39a208472 | |
Timothy Stack | f43d05a49a | |
Tim Stack | d570a86232 | |
Suresh Sundriyal | 63ed3ee677 | |
Timothy Stack | a5171058c7 | |
Timothy Stack | d8bc5b71c8 | |
Timothy Stack | 8ff80ceff0 | |
Tim Stack | d58ce0cc90 | |
Timothy Stack | 48d4b51fd7 | |
Suresh Sundriyal | 46e97f67df | |
Suresh Sundriyal | 70847429fa | |
Tim Stack | 49ae32a986 | |
Suresh Sundriyal | 2062a0c740 | |
Tim Stack | 89cb6fbe76 | |
Suresh Sundriyal | a6920cc320 | |
Suresh Sundriyal | f35f855458 | |
Suresh Sundriyal | bc0dc337ef | |
Timothy Stack | 37b9b346a9 | |
Timothy Stack | 99805c61bb | |
Timothy Stack | e8e89ad0fd | |
Tim Stack | 5b7e5a7513 | |
Tim Stack | 8fe8654d23 | |
Suresh Sundriyal | a14d47ae76 | |
Suresh Sundriyal | bc09aad96c | |
Suresh Sundriyal | 4946f79ec1 | |
Suresh Sundriyal | 57e0b9f3f3 | |
Suresh Sundriyal | d118a60a36 | |
Timothy Stack | ba4b31b24a | |
Timothy Stack | 7d886a4e29 | |
Timothy Stack | e6c8f49c29 | |
Timothy Stack | cfc285ce2d | |
Suresh Sundriyal | 8646204c5d | |
Suresh Sundriyal | 24b964c65d | |
Suresh Sundriyal | 0dedb3d455 | |
Timothy Stack | cc12e6359c | |
Timothy Stack | da772a6486 | |
Timothy Stack | 4bf048d974 | |
Timothy Stack | f1a47ac1ad | |
Timothy Stack | 90ab6ea8f1 | |
Timothy Stack | ee572a2c86 | |
Tim Stack | c724a44bf4 | |
Timothy Stack | dbe252c70c | |
Timothy Stack | bbf06e78ba | |
Timothy Stack | cc7cba6514 | |
Timothy Stack | c18850aa01 | |
Tim Stack | 648b78359a | |
Suresh Sundriyal | 271c961085 | |
Timothy Stack | be106fcb8d | |
Timothy Stack | 692cf37e1b | |
Timothy Stack | 5e1f43b4c7 | |
Timothy Stack | 9773efd3a5 | |
Timothy Stack | ce0383dee1 | |
Tim Stack | c3f7eac29d | |
Suresh Sundriyal | 9a49035ce6 | |
Suresh Sundriyal | 7494f5cef5 | |
Suresh Sundriyal | 9b2b9d50ba | |
Suresh Sundriyal | 908c41cb64 | |
Suresh Sundriyal | 1b5fa6d92d | |
Tim Stack | 94e09c5228 | |
Suresh Sundriyal | a24aa5e414 | |
Suresh Sundriyal | 83a3e69118 | |
Suresh Sundriyal | 2d30bfd322 | |
Timothy Stack | 16c5fdccb4 | |
Timothy Stack | 783c23b62c | |
Tim Stack | 0fa78a3c9f | |
Timothy Stack | f9b3884b5e | |
Timothy Stack | 349991a695 | |
Timothy Stack | 3692c76788 | |
Amos Bird | 73d41228a9 | |
Timothy Stack | f383af4d5f | |
Timothy Stack | f3d172c831 | |
Tim Stack | 3438ad1da9 | |
Suresh Sundriyal | fb51c2fd4a | |
Timothy Stack | a3264fb104 | |
Timothy Stack | 8a3fbe6375 | |
Timothy Stack | 815a05577e | |
Timothy Stack | 8734795505 | |
Timothy Stack | ba1bc28209 | |
Timothy Stack | 82b34bb02a | |
Timothy Stack | ead1d3eb36 | |
Timothy Stack | c5a82240ec | |
Timothy Stack | 84a7079e3f | |
Timothy Stack | d6e1fd1f32 | |
Timothy Stack | 0aa31964aa | |
Timothy Stack | a9dda41baf | |
Timothy Stack | f0934a6e3c | |
Timothy Stack | 0940e97b2b | |
Timothy Stack | 9b751940ae | |
Timothy Stack | eb88ec4f6c | |
Timothy Stack | 1f2cf13739 | |
Timothy Stack | b408740697 | |
Timothy Stack | 6182b6b41c | |
Timothy Stack | 4fa4a7057b | |
Timothy Stack | d0f2f9e800 | |
Timothy Stack | 164477a5fe | |
Timothy Stack | a2b3427502 | |
Timothy Stack | 1269654617 | |
Timothy Stack | e451c7c112 | |
Timothy Stack | d695febe14 | |
Timothy Stack | 2a37a9ce7f | |
Timothy Stack | 45630545ed | |
Timothy Stack | bda6fe46b1 | |
Timothy Stack | ae08c12aa0 | |
Tim Stack | 4f9ff532fa | |
Tim Stack | 3946024e43 | |
Tim Stack | f956db916c | |
Tim Stack | 80b1576e63 | |
Tim Stack | f29f93978d | |
Tim Stack | ef8e89d9ff | |
Timothy Stack | d040e75d42 | |
Timothy Stack | e0181a0adb | |
Tim Stack | 0dfff0936b | |
Timothy Stack | 4250fe9c67 | |
Timothy Stack | d2b9d1cd1c | |
Timothy Stack | 07d5aba7b5 | |
Timothy Stack | ebd1038057 | |
Timothy Stack | 7a0cb4359c | |
Timothy Stack | ee7ffb7194 | |
Timothy Stack | 9c3f0eee89 | |
Timothy Stack | e85fff0b88 | |
Timothy Stack | 468a5ea5d2 | |
Timothy Stack | e3ac0e5825 | |
Timothy Stack | adb18eeea3 | |
Timothy Stack | 9cbe4d73a9 | |
Timothy Stack | defb00303f | |
Timothy Stack | 6073464722 | |
Timothy Stack | a8e97a180b | |
Timothy Stack | f23791af18 | |
Timothy Stack | c6196fe79f | |
Timothy Stack | 8f4149db94 | |
Timothy Stack | 8e9ef5765f | |
Timothy Stack | 7e36c6b3d0 | |
Timothy Stack | 8413dd13d8 | |
Timothy Stack | 99a8eb9850 | |
Timothy Stack | 9b28a90ab0 | |
Timothy Stack | 7e538c85f9 | |
Timothy Stack | 8a0193691f | |
Timothy Stack | 3da3ec799a | |
Timothy Stack | 138a506b1a | |
Timothy Stack | 0744a9b6de | |
Timothy Stack | d5373abeb4 | |
Timothy Stack | 441833ac23 | |
Timothy Stack | 1ca7cbcd82 | |
Timothy Stack | b5e81fa8fd | |
Timothy Stack | 77834a7576 | |
Timothy Stack | eef28d61a6 | |
Timothy Stack | 92f28f1174 | |
Timothy Stack | 07f4b56646 | |
Tim Stack | eb426afe36 | |
Stéphane Blondon | 70ed1c9af7 | |
Tim Stack | c048290474 | |
edr | 3e82a06302 | |
Tim Stack | f152107857 | |
Aurélien Rouëné | 9313b372a1 | |
Aurélien Rouëné | f8ef4c1b17 | |
Timothy Stack | 9db2dfa7a4 | |
Tim Stack | 2ed88815da | |
Timothy Stack | e525d247ae | |
Timothy Stack | 10b8d64b03 | |
Timothy Stack | 8b750c83f1 | |
Timothy Stack | 0935e1c356 | |
Timothy Stack | 5901c92794 | |
Timothy Stack | 98519b045a | |
Timothy Stack | b7255419e6 | |
Timothy Stack | 9d6e6e4638 | |
Timothy Stack | 27587ee917 | |
Tim Stack | 03dc27f30a | |
Tim Stack | b2463e44a3 | |
Timothy Stack | f11364660d | |
Timothy Stack | 73e902f7d8 | |
Timothy Stack | cd3b9bbb71 | |
Phil Hord | 5513deeade | |
Timothy Stack | 165cd69c8d | |
Timothy Stack | 585986057d | |
Timothy Stack | 56a341f7f8 | |
Timothy Stack | 9a05b9d186 | |
Timothy Stack | 07cc749c50 | |
Timothy Stack | 71f56d29da | |
Timothy Stack | ed67c6cf9f | |
Timothy Stack | 3669b73e5b | |
Timothy Stack | e442f84e80 | |
Timothy Stack | 63dba408ec | |
Tim Stack | 74d026cb76 | |
Darragh O'Reilly | 6e93145f23 | |
Timothy Stack | ffd9d88add | |
Timothy Stack | 34db64aa32 | |
Timothy Stack | d381197195 | |
Timothy Stack | e6590e94e2 | |
Timothy Stack | 65d2f7552c | |
Timothy Stack | 91dd8a84ec | |
Timothy Stack | 76ea0abcd9 | |
Timothy Stack | 7c485f64dc | |
Timothy Stack | fa1217e2f6 | |
Timothy Stack | 0882f95ef4 | |
Timothy Stack | 8bb1d4a732 | |
Timothy Stack | 1257fcd62a | |
Timothy Stack | ea7663feba | |
Timothy Stack | 325e4a15d9 | |
Timothy Stack | 76edd2a9d1 | |
Timothy Stack | b81b35c866 | |
Timothy Stack | d61f2568d6 | |
Timothy Stack | de6ec92f2f | |
Timothy Stack | a9e9613214 | |
Timothy Stack | 26ada4dd2f | |
Timothy Stack | e27cf3b158 | |
Timothy Stack | a10fa06b10 | |
Timothy Stack | 02c53976b4 | |
Timothy Stack | b5c6ed6240 | |
Timothy Stack | f0000ae065 | |
Timothy Stack | e18e8e214a | |
Timothy Stack | 0918063640 | |
Timothy Stack | 6cf5cc8213 | |
Timothy Stack | 3c85936999 | |
Timothy Stack | 1fc24ecabf | |
Timothy Stack | c7046b0b54 | |
Timothy Stack | bb6f31eaa0 | |
Timothy Stack | ecd17a9f97 | |
Timothy Stack | 76b08f5fe3 | |
Timothy Stack | e80ec6ec73 | |
Timothy Stack | 28a275e4fb | |
Timothy Stack | 65d9240300 | |
Timothy Stack | fb7d6eafaf | |
Timothy Stack | 63e53377c3 | |
Timothy Stack | 147dea9d8c | |
Timothy Stack | a8e1f62da6 | |
Timothy Stack | a648657ff3 | |
Timothy Stack | fc9f9f43cf | |
Timothy Stack | e8f4020c67 | |
Timothy Stack | 06d1098211 | |
Matt Hayden | e66bf9213b | |
Matt Hayden | 66285bbb62 | |
Timothy Stack | 6f451eec35 | |
Timothy Stack | 5e8a1cebe9 | |
Timothy Stack | 832f980ab9 | |
Tim Stack | 776705e90e | |
Matt Hayden (Innolitics) | ba48d31120 | |
Timothy Stack | 062d480fea | |
Timothy Stack | 2fa603d07e | |
Timothy Stack | c4b950e4d9 | |
Timothy Stack | 78d80fddd5 | |
Timothy Stack | 8d3b83403c | |
Timothy Stack | 33cdbefaaa | |
Timothy Stack | 21c5c52843 | |
Timothy Stack | 0e12f98ae7 | |
Timothy Stack | 0de761ce4f | |
Timothy Stack | 469124d72b | |
Timothy Stack | 6f41cbe394 | |
Timothy Stack | efa6aded3a | |
Timothy Stack | bc4004de9e | |
Timothy Stack | 4614cbcb75 | |
Timothy Stack | 43243c7ba3 | |
Tim Stack | 0f6860c833 | |
Tim Stack | df8844eb77 | |
Tim Stack | bdf202e487 | |
Tim Stack | 8ad095fc71 | |
Timothy Stack | 9fea61abf8 | |
Timothy Stack | d62da7c27c | |
Timothy Stack | 02b9e13343 | |
Timothy Stack | a682b02168 | |
Timothy Stack | 659f01c9ae | |
Timothy Stack | e0ee2c6706 | |
Timothy Stack | 1e795c1e4a | |
Timothy Stack | 4a7d116f37 | |
Timothy Stack | d66303b75a | |
Timothy Stack | 153b59ea8a | |
Timothy Stack | 1a932f3a41 | |
Timothy Stack | d1a556638b | |
Timothy Stack | 104b8736e8 | |
Timothy Stack | 527150d6a0 | |
Timothy Stack | 3d77fb2acf | |
Timothy Stack | 8a3bdbfb2f | |
Timothy Stack | 9936f1e814 | |
Timothy Stack | 31c440777f | |
Timothy Stack | 69508e6467 | |
Timothy Stack | 0c2f84a3c0 | |
Timothy Stack | 85671755d3 | |
Timothy Stack | 5fff4d8784 | |
Timothy Stack | 6853034cce | |
Timothy Stack | e451e10910 | |
Timothy Stack | 4381c23641 | |
Timothy Stack | dcccebe797 | |
Timothy Stack | 7dfa0e9dd4 | |
Timothy Stack | 66ef968529 | |
Timothy Stack | d65a8be9d1 | |
Timothy Stack | 7c95941920 | |
Timothy Stack | cdbf4dabda | |
Timothy Stack | a63b6a199c | |
Timothy Stack | 814ad03ec9 | |
Tim Stack | 7fe811da07 | |
Timothy Stack | 5769bcbb4a | |
Timothy Stack | 42be76c3ba | |
Timothy Stack | d46cfa1a8c | |
Timothy Stack | afef6b1827 | |
Timothy Stack | f2b9988c95 | |
Timothy Stack | e001b49e28 | |
Timothy Stack | b4e7bc9b0f | |
Timothy Stack | 1a08eb0d12 | |
Timothy Stack | 49dce3cec2 | |
Timothy Stack | aae4650b95 | |
Timothy Stack | 2c5bfc830e | |
Timothy Stack | 8b5b8743b1 | |
Timothy Stack | 64d4226a89 | |
Timothy Stack | b53ac5e3a6 | |
Timothy Stack | 5c6cc5fe2a | |
Timothy Stack | 31a19ac753 | |
Timothy Stack | 6336fa56e9 | |
Timothy Stack | f6a84ed081 | |
Timothy Stack | aa0bfd6c62 | |
Timothy Stack | ec82ecda62 | |
Timothy Stack | efe6ccf0d1 | |
Timothy Stack | 2345a32423 |
|
@ -0,0 +1,5 @@
|
|||
freebsd_instance:
|
||||
image: freebsd-12-1-release-amd64
|
||||
task:
|
||||
install_script: pkg install -y wget git m4 bash autoconf automake sqlite3 gmake
|
||||
build_script: ./autogen.sh && ./configure && gmake -j3
|
|
@ -0,0 +1,178 @@
|
|||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Chromium
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: DontAlign
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
# AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: MultiLine
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: Custom
|
||||
# BreakBeforeInheritanceComma: true
|
||||
BreakInheritanceList: BeforeComma
|
||||
BreakBeforeTernaryOperators: true
|
||||
# BreakConstructorInitializersBeforeComma: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: true
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
# Standard library headers come before anything else
|
||||
- Regex: '^<[a-z_]+>'
|
||||
Priority: -1
|
||||
- Regex: '^<.+\.h(pp)?>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: ''
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentExternBlock: NoIndent
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: Wrapped
|
||||
JavaScriptQuotes: Double
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Never
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 4
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
RawStringFormats:
|
||||
- Language: Cpp
|
||||
Delimiters:
|
||||
- cc
|
||||
- CC
|
||||
- cpp
|
||||
- Cpp
|
||||
- CPP
|
||||
- 'c++'
|
||||
- 'C++'
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
- Language: TextProto
|
||||
Delimiters:
|
||||
- pb
|
||||
- PB
|
||||
- proto
|
||||
- PROTO
|
||||
EnclosingFunctions:
|
||||
- EqualsProto
|
||||
- EquivToProto
|
||||
- PARSE_PARTIAL_TEXT_PROTO
|
||||
- PARSE_TEST_PROTO
|
||||
- PARSE_TEXT_PROTO
|
||||
- ParseTextOrDie
|
||||
- ParseTextProtoOrDie
|
||||
- ParseTestProto
|
||||
- ParsePartialTestProto
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
ReflowComments: true
|
||||
SortIncludes: CaseInsensitive
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatementsExceptForEachMacros
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
Standard: Auto
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
...
|
|
@ -0,0 +1,162 @@
|
|||
---
|
||||
# Enable ALL the things! Except not really
|
||||
# misc-non-private-member-variables-in-classes: the options don't do anything
|
||||
Checks: >
|
||||
*,
|
||||
-google-readability-todo,
|
||||
-altera-unroll-loops,
|
||||
-altera-id-dependent-backward-branch,
|
||||
-altera-struct-pack-align,
|
||||
-fuchsia-*,
|
||||
fuchsia-multiple-inheritance,
|
||||
-llvm-header-guard,
|
||||
-llvm-include-order,
|
||||
-llvmlibc-*,
|
||||
-modernize-use-trailing-return-type,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-cppcoreguidelines-pro-type-vararg,
|
||||
-hicpp-vararg,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
-hicpp-avoid-c-arrays,
|
||||
-modernize-avoid-c-arrays
|
||||
WarningsAsErrors: ''
|
||||
CheckOptions:
|
||||
- key: 'bugprone-argument-comment.StrictMode'
|
||||
value: 'true'
|
||||
# Prefer using enum classes with 2 values for parameters instead of bools
|
||||
- key: 'bugprone-argument-comment.CommentBoolLiterals'
|
||||
value: 'true'
|
||||
- key: 'bugprone-misplaced-widening-cast.CheckImplicitCasts'
|
||||
value: 'true'
|
||||
- key: 'bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression'
|
||||
value: 'true'
|
||||
- key: 'bugprone-suspicious-string-compare.WarnOnLogicalNotComparison'
|
||||
value: 'true'
|
||||
- key: 'readability-simplify-boolean-expr.ChainedConditionalReturn'
|
||||
value: 'true'
|
||||
- key: 'readability-simplify-boolean-expr.ChainedConditionalAssignment'
|
||||
value: 'true'
|
||||
- key: 'readability-uniqueptr-delete-release.PreferResetCall'
|
||||
value: 'true'
|
||||
- key: 'cppcoreguidelines-init-variables.MathHeader'
|
||||
value: '<cmath>'
|
||||
- key: 'cppcoreguidelines-narrowing-conversions.PedanticMode'
|
||||
value: 'true'
|
||||
- key: 'readability-else-after-return.WarnOnUnfixable'
|
||||
value: 'true'
|
||||
- key: 'readability-else-after-return.WarnOnConditionVariables'
|
||||
value: 'true'
|
||||
- key: 'readability-inconsistent-declaration-parameter-name.Strict'
|
||||
value: 'true'
|
||||
- key: 'readability-qualified-auto.AddConstToQualified'
|
||||
value: 'true'
|
||||
- key: 'readability-redundant-access-specifiers.CheckFirstDeclaration'
|
||||
value: 'true'
|
||||
# These seem to be the most common identifier styles
|
||||
- key: 'readability-identifier-naming.AbstractClassCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ClassCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ClassConstantCase'
|
||||
value: 'UPPER_CASE'
|
||||
- key: 'readability-identifier-naming.ClassMemberCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ClassMethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ConstantCase'
|
||||
value: 'UPPER_CASE'
|
||||
- key: 'readability-identifier-naming.ConstantMemberCase'
|
||||
value: 'UPPER_CASE'
|
||||
- key: 'readability-identifier-naming.ConstantParameterCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ConstantPointerParameterCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ConstexprFunctionCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ConstexprMethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ConstexprVariableCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.EnumCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.EnumConstantCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.FunctionCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.GlobalConstantCase'
|
||||
value: 'UPPER_CASE'
|
||||
- key: 'readability-identifier-naming.GlobalConstantPointerCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.GlobalFunctionCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.GlobalPointerCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.GlobalVariableCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.InlineNamespaceCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.LocalConstantCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.LocalConstantPointerCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.LocalPointerCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.LocalVariableCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.MacroDefinitionCase'
|
||||
value: 'UPPER_CASE'
|
||||
- key: 'readability-identifier-naming.MemberCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.MethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.NamespaceCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ParameterCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ParameterPackCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.PointerParameterCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.PrivateMemberCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.PrivateMethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ProtectedMemberCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ProtectedMethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.PublicMemberCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.PublicMethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ScopedEnumConstantCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.StaticConstantCase'
|
||||
value: 'UPPER_CASE'
|
||||
- key: 'readability-identifier-naming.StaticVariableCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.StructCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.TemplateParameterCase'
|
||||
value: 'CamelCase'
|
||||
- key: 'readability-identifier-naming.TemplateTemplateParameterCase'
|
||||
value: 'CamelCase'
|
||||
- key: 'readability-identifier-naming.TypeAliasCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.TypedefCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.TypeTemplateParameterCase'
|
||||
value: 'CamelCase'
|
||||
- key: 'readability-identifier-naming.UnionCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.ValueTemplateParameterCase'
|
||||
value: 'CamelCase'
|
||||
- key: 'readability-identifier-naming.VariableCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-naming.VirtualMethodCase'
|
||||
value: 'lower_case'
|
||||
- key: 'readability-identifier-length.MinimumVariableNameLength'
|
||||
value: '2'
|
||||
- key: 'readability-identifier-length.MinimumParameterNameLength'
|
||||
value: '2'
|
||||
...
|
|
@ -0,0 +1,6 @@
|
|||
[codespell]
|
||||
builtin = clear,rare,en-GB_to_en-US,names,informal,code
|
||||
check-filenames =
|
||||
check-hidden =
|
||||
skip = */.git,*/build,*/prefix,*/conan
|
||||
quiet-level = 2
|
|
@ -0,0 +1,2 @@
|
|||
service_name: github-actions
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**lnav version**
|
||||
v0.11.1 is the latest
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"ignorePatterns": [
|
||||
{
|
||||
"pattern": "^/assets"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://archive.org"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
name: ci-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
tags: ['*']
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
coverage:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# - name: Update apt
|
||||
# run: sudo apt-get update
|
||||
# - name: Install packages
|
||||
# run: sudo apt-get install libncursesw5-dev libpcre++-dev libsqlite3-dev libbz2-dev libcurl4-openssl-dev libreadline-dev zlib1g-dev lcov
|
||||
# - name: install cpp-coveralls
|
||||
# run: pip install --user cpp-coveralls
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure --disable-static --enable-code-coverage --enable-debug CFLAGS=-g3 CXXFLAGS=-g3
|
||||
- name: make
|
||||
run: make -j3
|
||||
- name: make check
|
||||
run: make check
|
||||
- name: upload cover
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
||||
TRAVIS_JOB_ID: ${{ github.run_id }}-${{ github.run_number }}
|
||||
run: >-
|
||||
coveralls
|
||||
--exclude src/doctest.hh
|
||||
--exclude src/fmtlib
|
||||
--exclude src/ghc
|
||||
--exclude src/k_merge_tree.h
|
||||
--exclude src/mapbox
|
||||
--exclude src/pugixml
|
||||
--exclude src/base/result.h
|
||||
--exclude src/safe
|
||||
--exclude src/spookyhash
|
||||
--exclude src/third-party
|
||||
--exclude src/ww898
|
||||
--exclude src/yajl
|
||||
--exclude test
|
||||
--exclude src/data_scanner_re.cc
|
||||
--gcov-options '\-lp'
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Update apt
|
||||
run: sudo apt-get update
|
||||
- name: Install packages
|
||||
run: >-
|
||||
sudo apt-get install -y
|
||||
make
|
||||
automake
|
||||
autoconf
|
||||
g++
|
||||
libpcre2-dev
|
||||
libpcre3-dev
|
||||
libncurses-dev
|
||||
libsqlite3-dev
|
||||
libbz2-dev
|
||||
libcurl4-openssl-dev
|
||||
libreadline-dev
|
||||
tshark
|
||||
zlib1g-dev
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure --disable-static
|
||||
- name: make
|
||||
run: make -j4
|
||||
- name: make distcheck
|
||||
run: make distcheck -j4 || (test -e lnav-*/_build/sub/src/tailer/test-suite.log && cat lnav-*/_build/sub/src/tailer/test-suite.log && false) || (test -e lnav-*/_build/sub/test/test-suite.log && cat lnav-*/_build/sub/test/test-suite.log && false)
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
# Artifact name
|
||||
name: lnav-tot-linux-64bit.zip
|
||||
# A file, directory or wildcard pattern that describes what to upload
|
||||
path: src/lnav
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { icon: '🟦', sys: MSYS }
|
||||
name: ${{ matrix.icon }} ${{ matrix.sys }}
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: '🧰 Checkout'
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: '${{ matrix.icon }} Setup MSYS2'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{matrix.sys}}
|
||||
update: true
|
||||
install: >-
|
||||
autoconf
|
||||
automake
|
||||
gcc
|
||||
git
|
||||
make
|
||||
zip
|
||||
msys/libarchive-devel
|
||||
msys/libbz2-devel
|
||||
msys/libcurl-devel
|
||||
msys/libidn2-devel
|
||||
msys/liblzma-devel
|
||||
msys/libreadline-devel
|
||||
msys/libsqlite-devel
|
||||
msys/libunistring-devel
|
||||
msys/ncurses-devel
|
||||
msys/pcre2-devel
|
||||
msys/zlib-devel
|
||||
- name: '🔧 Generate and configure'
|
||||
run: |
|
||||
set -x
|
||||
./autogen.sh
|
||||
mkdir -p ../lnav-build
|
||||
cd ../lnav-build
|
||||
export PREFIX=$PWD/lnav
|
||||
../lnav/configure \
|
||||
--enable-static \
|
||||
LDFLAGS="-static" \
|
||||
CPPFLAGS="-I../src -I../../lnav/src -I../../lnav/src/fmtlib -O2 -DNCURSES_STATIC" \
|
||||
CXXFLAGS="-fPIC" \
|
||||
CFLAGS="-fPIC" \
|
||||
LIBS="-larchive -lssh2 -llzma -llz4 -lz -lzstd -lssl -lcrypto -liconv -lunistring -lbrotlicommon" \
|
||||
--sysconfdir=/etc \
|
||||
--prefix=$PREFIX || cat config.log
|
||||
- name: '🚧 Make (do not use -j)'
|
||||
run: |
|
||||
set -x
|
||||
cd ../lnav-build
|
||||
make CFLAGS="-c"
|
||||
strip -s src/lnav.exe
|
||||
- name: '📦 Package for distribution'
|
||||
run: |
|
||||
set -x
|
||||
cd ../lnav-build
|
||||
export PREFIX=$PWD/lnav
|
||||
make install
|
||||
ldd $PREFIX/bin/lnav.exe | grep /usr | cut -d' ' -f3 | xargs -I {} cp {} $PREFIX/bin/
|
||||
mkdir -p lib/terminfo/78
|
||||
cp -r /usr/lib/terminfo/78/xterm-256color lib/terminfo/78/
|
||||
zip -r ../lnav/lnav-${{ github.ref_name }}-windows-amd64.zip lnav lib
|
||||
- name: '💉 Basic test'
|
||||
run: |
|
||||
set -x
|
||||
cd ../lnav-build
|
||||
export PREFIX=$PWD/lnav
|
||||
$PREFIX/bin/lnav.exe -n ../lnav/test/logfile_multiline.0
|
||||
- name: '⬆️ Upload a Build Artifact'
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: lnav-${{ github.ref_name }}-windows-amd64.zip
|
||||
path: lnav-${{ github.ref_name }}-windows-amd64.zip
|
||||
if-no-files-found: error
|
||||
# - name: '🎁 Create Release'
|
||||
# id: create_release
|
||||
# uses: actions/create-release@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# tag_name: ${{ github.ref_name }}
|
||||
# release_name: Release ${{ github.ref_name }}
|
||||
# draft: false
|
||||
# prerelease: false
|
||||
# - name: '⬆️ Upload Release Asset'
|
||||
# id: upload-release-asset
|
||||
# uses: actions/upload-release-asset@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||
# asset_path: ./lnav-${{ github.ref_name }}-windows-amd64.zip
|
||||
# asset_name: lnav-${{ github.ref_name }}-windows-amd64.zip
|
||||
# asset_content_type: application/zip
|
|
@ -0,0 +1,12 @@
|
|||
name: Check Markdown links
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
markdown-link-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
with:
|
||||
config-file: '.github/mlc_config.json'
|
|
@ -0,0 +1,48 @@
|
|||
# GitHub actions workflow.
|
||||
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
|
||||
|
||||
name: Coverity Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
schedule:
|
||||
# The GH mirroring from Google GoB does not trigger push actions.
|
||||
# Fire it once a week to provide some coverage.
|
||||
- cron: '39 2 * * WED'
|
||||
|
||||
# Allow for manual triggers from the web.
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
coverity:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Update apt
|
||||
run: sudo apt-get update
|
||||
- name: Install packages
|
||||
run: >-
|
||||
sudo apt-get install -y
|
||||
make
|
||||
automake
|
||||
autoconf
|
||||
g++
|
||||
libpcre3-dev
|
||||
libncurses-dev
|
||||
libsqlite3-dev
|
||||
libbz2-dev
|
||||
libcurl4-openssl-dev
|
||||
libreadline-dev
|
||||
tshark
|
||||
zlib1g-dev
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure --disable-static
|
||||
- uses: vapier/coverity-scan-action@v1
|
||||
with:
|
||||
command: make -j$(getconf _NPROCESSORS_CONF)
|
||||
email: ${{ secrets.COVERITY_SCAN_EMAIL }}
|
||||
token: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
|
@ -0,0 +1,33 @@
|
|||
name: tailer-ape
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: update apt
|
||||
run: sudo apt-get update
|
||||
- name: Install packages
|
||||
run: >-
|
||||
wget https://github.com/tstack/cosmopolitan/releases/download/v1.0stack/cosmopolitan-amalgamation-1.0-stack.zip &&
|
||||
unzip cosmopolitan-amalgamation-1.0-stack.zip
|
||||
- name: Build
|
||||
run: >-
|
||||
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone
|
||||
-fno-omit-frame-pointer -pg -mnop-mcount
|
||||
-o tailer.dbg -I src/tailer
|
||||
src/tailer/tailer.main.c src/tailer/tailer.c src/tailer/sha-256.c
|
||||
-fuse-ld=bfd -Wl,-T,ape.lds
|
||||
-include cosmopolitan.h crt.o ape.o cosmopolitan.a
|
||||
- name: Objcopy
|
||||
run: objcopy -S -O binary tailer.dbg src/tailer/tailer.ape
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
# Optional, but recommended
|
||||
# Defaults to "Apply automatic changes"
|
||||
commit_message: Update tailer
|
||||
file_pattern: src/tailer/tailer.ape
|
|
@ -2,7 +2,7 @@
|
|||
.lnav
|
||||
*.dat
|
||||
*.diff
|
||||
*.err
|
||||
test/*.err
|
||||
*.index
|
||||
*.log
|
||||
*.o
|
||||
|
@ -10,10 +10,13 @@
|
|||
*.pyc
|
||||
*.tmp
|
||||
*.trs
|
||||
*~
|
||||
.idea/
|
||||
Makefile
|
||||
Makefile.in
|
||||
TESTS_ENVIRONMENT
|
||||
aclocal.m4
|
||||
aminclude_static.am
|
||||
ar-lib
|
||||
autom4te.cache
|
||||
compile
|
||||
|
@ -28,12 +31,14 @@ missing
|
|||
mkinstalldirs
|
||||
test-driver
|
||||
docs/build
|
||||
release/release-NEWS.md
|
||||
release/linux-pkg/
|
||||
release/osx-build-dir/
|
||||
release/osx-pkg/
|
||||
release/outbox/
|
||||
release/vagrant-static-linux/.vagrant
|
||||
release/vagrant-static-linux/lnav
|
||||
cmake-build-debug/
|
||||
src/bin2c
|
||||
src/config.h
|
||||
src/config.h.in
|
||||
|
@ -87,3 +92,13 @@ test/test_pcrepp
|
|||
test/test_top_status
|
||||
test/test_yajlpp
|
||||
test/truncfile.0
|
||||
cmake-build/
|
||||
.vs/
|
||||
.vscode/
|
||||
build/
|
||||
cmake/open-cpp-coverage.cmake
|
||||
cmake-build-*/
|
||||
conan/
|
||||
prefix/
|
||||
CMakeLists.txt.user
|
||||
CMakeUserPresets.json
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF
|
||||
formats:
|
||||
- pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
48
.travis.yml
|
@ -1,48 +0,0 @@
|
|||
|
||||
dist: xenial
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
sudo: false
|
||||
install:
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-5" CC="gcc-5"; fi
|
||||
script: ./autogen.sh && ./configure LDFLAGS="-static-libstdc++ -static-libgcc" && make distcheck -j3
|
||||
after_script: test -e lnav-*/_build/test/test-suite.log && cat lnav-*/_build/test/test-suite.log
|
||||
|
||||
env:
|
||||
global:
|
||||
- LDFLAGS: -static-libstdc++ -static-libgcc
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "P3wQLswiGYWrZwO4bxFmsA4XG5s/pS+renL0RMeotMTQwQQXmy1ZCvwMnAgaYWQmF82fN8WjuhO3OX0gpDbydxRktqI5ZqblsryV6poB0g+OkCqThbDUp3TL6TjPqySTI1CZ8qoOBYFMubAZYVJAEfxl0UxoQE+uTsRarRqr8rI="
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libgpm-dev
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- sqlite3
|
||||
- language-pack-fr
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: deb http://cz.archive.ubuntu.com/ubuntu xenial main
|
||||
coverity_scan:
|
||||
project:
|
||||
name: tstack/lnav
|
||||
description: Your project description here
|
||||
notification_email: timothyshanestack@gmail.com
|
||||
build_command_prepend: ./autogen.sh && ./configure
|
||||
build_command: make
|
||||
branch_pattern: coverity_scan
|
||||
deploy:
|
||||
provider: releases
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
secure: BQOrhEaDcR53WPGDmBj8UcCtcUjmuTb5g4u1oNhIiF0G5+8UweXOquLf8c52uIkUBYuruc/TB7qWGNisO3skSTh9t8+6v6PE1EAwk5PzavsQqqCmGF32izw75B8TC6SFWQY7AFyKjIc/bHxyz0FA0L2YtvMREtF3jF9ezGek07Y=
|
||||
file: lnav*.zip
|
||||
file_glob: true
|
||||
on:
|
||||
tags: true
|
|
@ -0,0 +1,121 @@
|
|||
# Architecture
|
||||
|
||||
This document covers the internal architecture of the Logfile Navigator (lnav),
|
||||
a terminal-based tool for viewing and analyzing log files.
|
||||
|
||||
## Goals
|
||||
|
||||
The following goals drive the design and implementation of lnav:
|
||||
|
||||
- Don't make the user do something that can be done automatically.
|
||||
|
||||
Example: Automatically detect log formats for files instead of making them
|
||||
specify the format for each file.
|
||||
|
||||
- Be performant on low-spec hardware.
|
||||
|
||||
Example: Prefer single-threaded optimizations over trying to parallelize
|
||||
|
||||
- Operations should be "live" and not block the user from continuing to work.
|
||||
|
||||
Example: Searches are run in the background.
|
||||
|
||||
- Provide context-sensitive help.
|
||||
|
||||
Example: When the cursor is over a SQL keyword/function, the help text for
|
||||
that is shown above.
|
||||
|
||||
- Show a preview of operations so the user knows what is going to happen.
|
||||
|
||||
Example: When entering a `:filter-out` command, the matched parts of the
|
||||
lines are highlighted in red.
|
||||
|
||||
## Overview
|
||||
|
||||
The whole of lnav consists of a
|
||||
[log file parser](https://docs.lnav.org/en/latest/formats.html),
|
||||
[text UI](https://docs.lnav.org/en/latest/ui.html),
|
||||
[integrations with SQLite](https://docs.lnav.org/en/latest/sqlext.html),
|
||||
[command-line interface](https://docs.lnav.org/en/latest/cli.html), and
|
||||
[commands for operating on logs](https://docs.lnav.org/en/latest/commands.html).
|
||||
Since the majority of lnav's operations center around logs, the core
|
||||
data-structure is the combined log message index. The message index is populated
|
||||
when new messages are read from log files. The text UI displays a subset of
|
||||
messages from the index. The SQLite virtual-tables allow for programmatic access
|
||||
to the messages and lnav's internal state.
|
||||
|
||||
[![lnav architecture](docs/lnav-architecture.png)](https://whimsical.com/lnav-architecture-UM594Qo4G3nt2XWaSZA1mh)
|
||||
|
||||
## File Monitoring
|
||||
|
||||
Each file being monitored by lnav has an associated [`logfile`](src/logfile.hh)
|
||||
object, be they plaintext files or files with a recognized format. These
|
||||
objects are periodically polled by the main event loop to check if the file
|
||||
was deleted, truncated, or new lines added. While reading new lines, if no
|
||||
log format has matched yet, each line will be passed through the log format
|
||||
regular expressions to try and find a match. Each line that is read is added
|
||||
to an index
|
||||
|
||||
#### Why is `mmap()` not used?
|
||||
|
||||
Note that file contents are consumed using `pread(2)`/`read(2)` and not
|
||||
`mmap(2)` since `mmap(2)` does not react well to files changing out from
|
||||
underneath it. For example, a truncated file would likely result in a
|
||||
`SIGBUS`.
|
||||
|
||||
## Log Messages
|
||||
|
||||
As files are being indexed, if a matching format is found, the file is
|
||||
"promoted" from a plaintext file to a log file. When the file is promoted,
|
||||
it is added to the [logfile_sub_source](src/logfile_sub_source.hh), which
|
||||
collates all log messages together into a single index.
|
||||
|
||||
### Timestamp Parsing
|
||||
|
||||
Since all log messages need to have a timestamp, timestamp parsing needs to be
|
||||
very efficient. The standard `strptime()` function is quite expensive, so lnav
|
||||
includes an optimized custom parser and code-generator in the
|
||||
[ptimec](src/ptimec.hh) component. The code-generator is used at compile-time
|
||||
to generate parsers for several [common formats](src/time_formats.am).
|
||||
|
||||
## Log Formats
|
||||
|
||||
[log_format](src/log_format.hh) instances are used to parse lines from files
|
||||
into `logline` objects. The majority of log formats are
|
||||
[external_log_format](src/log_format_ext.hh) objects that are create from
|
||||
[JSON format definitions](https://docs.lnav.org/en/latest/formats.html). The
|
||||
built-in definitions are located in the [formats](src/formats) directory. Log
|
||||
formats that cannot be handled through a simple regular expression are
|
||||
implemented in the [log_format_impls.cc](src/log_format_impls.cc) file.
|
||||
|
||||
## User Interface
|
||||
|
||||
The lnav text-user-interface is built on top of
|
||||
[ncurses](https://invisible-island.net/ncurses/announce.html).
|
||||
However, the higher-level functionality of panels, widgets, and such is not
|
||||
used. Instead, the following custom components are built on top of the ncurses
|
||||
primitives:
|
||||
|
||||
- [view_curses](src/view_curses.hh) - Provides the basics for text roles, which
|
||||
allows for themes to color and style text. The `mvwattrline()` function does
|
||||
all the heavy lifting of drawing ["attributed" lines](src/base/attr_line.hh),
|
||||
which are strings that have attributes associated with a given range of
|
||||
characters.
|
||||
- [listview_curses](src/listview_curses.hh) - Displays a list of items that are
|
||||
provided by a source.
|
||||
- [textview_curses](src/textview_curses.hh) - Builds on the list view by adding
|
||||
support for searching, filtering, bookmarks, etc... The main panel that
|
||||
displays the logs/plaintext/help is a textview.
|
||||
- [statusview_curses](src/state-extension-functions.cc) - Draws the status bars
|
||||
at the top and bottom of the TUI.
|
||||
- [vt52_curses](src/vt52_curses.hh) - Adapts vt52 escape codes to the ncurses
|
||||
API.
|
||||
- [readline_curses](src/readline_curses.hh) - Provides access to the readline
|
||||
library. The readline code is executed in a child process since readline
|
||||
does not get along with ncurses. The child process and readline is set to
|
||||
use a vt52 terminal and the vt52_curses view is uses to translate those
|
||||
escape codes to ncurses.
|
||||
|
||||
The following diagram shows the underlying components that make up the TUI:
|
||||
|
||||
[![lnav TUI](docs/lnav-tui.png)](https://whimsical.com/lnav-tui-MQjXc7Vx23BxQTHrnuNp5F)
|
18
AUTHORS
|
@ -13,7 +13,7 @@ Christopher Meng
|
|||
Salvatore Bonaccorso
|
||||
Henrietta Stack
|
||||
Pablo Iranzo Gómez
|
||||
androm3da (https://github.com/androm3da)
|
||||
Brian Cain
|
||||
Paul Wayper
|
||||
Adam Spiers
|
||||
Kevin Pham
|
||||
|
@ -28,3 +28,19 @@ Jan Chren
|
|||
Geoff Crompton
|
||||
Medina Maza
|
||||
Phil Hord
|
||||
Tristan Ramseyer
|
||||
Aurélien Rouëné
|
||||
Emiliano Bonassi
|
||||
Darragh O'Reilly
|
||||
Stéphane Blondon
|
||||
Miguel Terron
|
||||
Enguerrand de Rochefort
|
||||
Nicolas Werner
|
||||
Matt Hayden
|
||||
Simos Xenitellis
|
||||
Finnegan Stack
|
||||
Amos Bird
|
||||
Cristian Chiru
|
||||
Peter Schiffer
|
||||
Pedro Pombeiro
|
||||
Fredrik Forséll
|
||||
|
|
|
@ -1,6 +1,59 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
include(cmake/prelude.cmake)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
project(
|
||||
lnav
|
||||
VERSION 0.11.1
|
||||
DESCRIPTION "An advanced log file viewer for the small-scale."
|
||||
HOMEPAGE_URL "https://lnav.org/"
|
||||
LANGUAGES CXX C
|
||||
)
|
||||
|
||||
include(cmake/project-is-top-level.cmake)
|
||||
include(cmake/variables.cmake)
|
||||
|
||||
find_package(SQLite3 REQUIRED)
|
||||
find_package(BZip2 REQUIRED)
|
||||
find_package(LibArchive REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(pcre REQUIRED)
|
||||
find_package(pcre2 REQUIRED)
|
||||
find_package(readline REQUIRED)
|
||||
find_package(ncurses REQUIRED)
|
||||
find_package(CURL REQUIRED)
|
||||
|
||||
set(lnav_LIBS
|
||||
CURL::libcurl
|
||||
SQLite::SQLite3
|
||||
BZip2::BZip2
|
||||
ncurses::libcurses
|
||||
pcre::libpcre
|
||||
pcre2::pcre2
|
||||
readline::readline
|
||||
LibArchive::LibArchive
|
||||
ZLIB::ZLIB
|
||||
)
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
SET(CMAKE_CXX_STANDARD 14)
|
||||
project (lnav)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
||||
# add_subdirectory(test)
|
||||
|
||||
# ---- Install rules ----
|
||||
|
||||
if (NOT CMAKE_SKIP_INSTALL_RULES)
|
||||
include(cmake/install-rules.cmake)
|
||||
endif ()
|
||||
|
||||
# ---- Developer mode ----
|
||||
|
||||
if (NOT lnav_DEVELOPER_MODE)
|
||||
return()
|
||||
elseif (NOT PROJECT_IS_TOP_LEVEL)
|
||||
message(
|
||||
AUTHOR_WARNING
|
||||
"Developer mode is intended for developers of lnav"
|
||||
)
|
||||
endif ()
|
||||
|
||||
include(cmake/dev-mode.cmake)
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
{
|
||||
"version": 2,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 14,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "cmake-pedantic",
|
||||
"hidden": true,
|
||||
"warnings": {
|
||||
"dev": true,
|
||||
"deprecated": true,
|
||||
"uninitialized": true,
|
||||
"unusedCli": true,
|
||||
"systemVars": false
|
||||
},
|
||||
"errors": {
|
||||
"dev": true,
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-mode",
|
||||
"hidden": true,
|
||||
"inherits": "cmake-pedantic",
|
||||
"cacheVariables": {
|
||||
"lnav_DEVELOPER_MODE": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "conan",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/conan/conan_toolchain.cmake"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "cppcheck",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_CPPCHECK": "cppcheck;--inline-suppr"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clang-tidy",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_CLANG_TIDY": "clang-tidy;--header-filter=${sourceDir}/*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-std",
|
||||
"description": "This preset makes sure the project actually builds with at least the specified standard",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_EXTENSIONS": "OFF",
|
||||
"CMAKE_CXX_STANDARD": "14",
|
||||
"CMAKE_CXX_STANDARD_REQUIRED": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "flags-unix",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "flags-windows",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "/W4 /permissive- /utf-8 /volatile:iso /EHsc /Zc:__cplusplus /Zc:throwingNew"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-unix",
|
||||
"generator": "Unix Makefiles",
|
||||
"hidden": true,
|
||||
"inherits": ["flags-unix", "ci-std"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-win64",
|
||||
"inherits": ["flags-windows", "ci-std"],
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"architecture": "x64",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "coverage-unix",
|
||||
"binaryDir": "${sourceDir}/build/coverage",
|
||||
"inherits": "ci-unix",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"ENABLE_COVERAGE": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Coverage",
|
||||
"CMAKE_CXX_FLAGS_COVERAGE": "-Og -g --coverage -fkeep-inline-functions -fkeep-static-functions",
|
||||
"CMAKE_EXE_LINKER_FLAGS_COVERAGE": "--coverage",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_COVERAGE": "--coverage",
|
||||
"CMAKE_MAP_IMPORTED_CONFIG_SANITIZE": "Coverage;RelWithDebInfo;Release;Debug;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-coverage",
|
||||
"inherits": ["coverage-unix", "dev-mode", "conan"],
|
||||
"cacheVariables": {
|
||||
"COVERAGE_HTML_COMMAND": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-sanitize",
|
||||
"binaryDir": "${sourceDir}/build/sanitize",
|
||||
"inherits": ["ci-unix", "dev-mode", "conan"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Sanitize",
|
||||
"CMAKE_CXX_FLAGS_SANITIZE": "-O2 -g -fsanitize=address,undefined -fno-omit-frame-pointer -fno-common",
|
||||
"CMAKE_MAP_IMPORTED_CONFIG_SANITIZE": "Sanitize;RelWithDebInfo;Release;Debug;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-build",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "ci-macos",
|
||||
"inherits": ["ci-build", "ci-unix", "dev-mode", "conan"]
|
||||
},
|
||||
{
|
||||
"name": "ci-ubuntu",
|
||||
"inherits": ["ci-build", "ci-unix", "clang-tidy", "conan", "dev-mode"]
|
||||
},
|
||||
{
|
||||
"name": "ci-windows",
|
||||
"inherits": ["ci-build", "ci-win64", "dev-mode", "conan"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"version": 2,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 14,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "dev-common",
|
||||
"hidden": true,
|
||||
"inherits": ["conan"],
|
||||
"cacheVariables": {
|
||||
"BUILD_MCSS_DOCS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-unix",
|
||||
"binaryDir": "${sourceDir}/build/dev-unix",
|
||||
"inherits": ["dev-common", "ci-unix", "dev-mode"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-win64",
|
||||
"binaryDir": "${sourceDir}/build/dev-win64",
|
||||
"inherits": ["dev-common", "ci-win64"]
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"binaryDir": "${sourceDir}/build/dev",
|
||||
"inherits": "dev-unix"
|
||||
},
|
||||
{
|
||||
"name": "dev-coverage",
|
||||
"binaryDir": "${sourceDir}/build/coverage",
|
||||
"inherits": ["dev-mode", "coverage-unix", "conan"]
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "dev",
|
||||
"configurePreset": "dev",
|
||||
"configuration": "Debug",
|
||||
"jobs": 4
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "dev",
|
||||
"configurePreset": "dev",
|
||||
"configuration": "Debug",
|
||||
"output": {
|
||||
"outputOnFailure": true
|
||||
},
|
||||
"execution": {
|
||||
"jobs": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
# These are supported funding model platforms
|
||||
github: [tstack]
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
ACLOCAL_AMFLAGS = -I .
|
||||
|
||||
SUBDIRS = src test
|
||||
SUBDIRS = tools src test
|
||||
|
||||
noinst_SCRIPTS = TESTS_ENVIRONMENT
|
||||
|
||||
|
|
516
NEWS
|
@ -1,516 +0,0 @@
|
|||
|
||||
lnav v0.8.5:
|
||||
Features:
|
||||
* The ":write-*" commands will now accept "/dev/clipboard" as a file name
|
||||
that writes to the system clipboard.
|
||||
* Added a ":redirect-to <path>" command to redirect command output to the
|
||||
given file. This command is mostly useful in scripts where one might
|
||||
want to redirect all output from commands like ":echo" and ":write-to -"
|
||||
to a single file.
|
||||
|
||||
Interface Changes:
|
||||
* The auto-complete behavior in the prompt has been modified to fall back
|
||||
to a fuzzy search if the prefix search finds no matches. For example,
|
||||
typing in ":fin" and pressing TAB would previously not do anything.
|
||||
Now, the ":fin" will be completed to ":filter-in " since that is a
|
||||
strong fuzzy match. If there are multiple matches, as would happen
|
||||
with ":dfil", readline's menu-complete behavior will be engaged and
|
||||
you can press TAB cycle through the options.
|
||||
|
||||
lnav v0.8.4:
|
||||
Features:
|
||||
* Added the ':comment' command that can be used to attach a comment to a
|
||||
log line. The comment will be displayed below the line, like so:
|
||||
2017-01-01T15:30:00 error: computer is on fire
|
||||
+ This is where it all went wrong
|
||||
The ':clear-comment' command will remove the attached comment. Comments
|
||||
are searchable with the standard search mechanism and they are available
|
||||
in SQL through the "log_comment" column.
|
||||
* Added the ':tag', ':untag', and ':delete-tags' commands that can be used
|
||||
to attach/detach tags on the top log line and delete all instances of
|
||||
a tag. Tags are also searchable and are available in SQL as a JSON
|
||||
array in the "log_tags" column.
|
||||
* Pressing left-arrow while viewing log messages will reveal the source
|
||||
file name for each line and the unique parts of the source path.
|
||||
Pressing again will reveal the full path.
|
||||
* The file name section of the top status line will show only the unique
|
||||
parts of the log file path if there is not enough room to show the full
|
||||
path.
|
||||
* Added the ":hide-unmarked-lines" and ":show-unmarked-lines" commands
|
||||
that hide/show lines based on whether they are bookmarked.
|
||||
* Added the "json_contains()" SQL function to check if a JSON value
|
||||
contains a number of a string.
|
||||
* The relative time parser recognizes "next" at the beginning of the
|
||||
input, for example, "next hour" or "next day". Handy for use in the
|
||||
":goto" command.
|
||||
* Added a "text-transform" option for formatting JSON log messages. The
|
||||
supported options are: none, uppercase, lowercase, and capitalize.
|
||||
* Added a special "__level__" field name for formatting JSON messages so
|
||||
that the lnav level name can be used instead of the internal value in
|
||||
the JSON object.
|
||||
* Added a log format for journald JSON logs.
|
||||
|
||||
Interface Changes:
|
||||
* When typing in a search, instead of moving the view to the first match
|
||||
that was found, the first ten matches will be displayed in the preview
|
||||
window.
|
||||
* The pretty-print view maintains highlighting from the log view.
|
||||
* The pretty-print view no longer tries to reverse lookup IP addresses.
|
||||
* The online help for commands and SQL functions now includes a 'See Also'
|
||||
section that lists related commands/functions.
|
||||
|
||||
Fixes:
|
||||
* The HOME key should now work in the command-prompt and move the cursor
|
||||
to the beginning of the line.
|
||||
* The :delete-filter command should now tab-complete existing filters.
|
||||
* Milliseconds can now be used in relative times (e.g. 10:00:00.123)
|
||||
* The J/K hotkeys were not marking lines correctly when the bottom of
|
||||
the view was reached.
|
||||
* The level field in JSON logs should now be recognized by the level
|
||||
patterns in the format.
|
||||
|
||||
lnav v0.8.3:
|
||||
Features:
|
||||
* Support for the Bro Network Security Monitor (https://www.bro.org) log
|
||||
file format.
|
||||
* Added an fstat() table-valued function for querying the local
|
||||
filesystem.
|
||||
* Added readlink() and realpath() SQL functions.
|
||||
* Highlights specified in log formats can now specify the colors to use
|
||||
for the highlighted parts of the log message.
|
||||
* Added a ":quit" command.
|
||||
* Added a "/ui/default-colors" configuration option to specify that the
|
||||
terminal's default background and foreground colors should be used
|
||||
instead of black and white.
|
||||
|
||||
Interface Changes:
|
||||
* Pressing delete at a command-prompt will exit the prompt if there is no
|
||||
other input.
|
||||
|
||||
Fixes:
|
||||
* The help view now includes all the command-help that would pop up as
|
||||
you entered commands and SQL queries.
|
||||
* Hidden fields and lines hidden before/after times are now saved in the
|
||||
current session and restored.
|
||||
* Unicode characters should now be displayed correctly (make sure you
|
||||
have LANG set to a UTF-8 locale).
|
||||
|
||||
lnav v0.8.2:
|
||||
Features:
|
||||
* The timestamp format for JSON log files can be specified with the
|
||||
"timestamp-format" option in the "line-format" array.
|
||||
* Added "min-width", "max-width", "align", and "overflow" options to the
|
||||
"line-format" in format definitions for JSON log files. These options
|
||||
give you more control over how the displayed line looks.
|
||||
* Added a "hidden" option to log format values so that you can hide JSON
|
||||
log fields from being displayed if they are not in the line format.
|
||||
* Added a "rewriter" field to log format value definitions that is a
|
||||
command used to rewrite the field in the pretty-printed version of a
|
||||
log message. For example, the HTTP access log format will rewrite the
|
||||
status code field to include the textual version (e.g. 200 (OK)).
|
||||
* Log message fields can now be hidden using the :hide-fields" command or
|
||||
by setting the 'hidden' property in the log format. When hidden, the
|
||||
fields will be replaced with a yellow ellipsis when displayed. Hiding
|
||||
large fields that contain extra details can make the log easier to read.
|
||||
The 'x' hotkey can be used to quickly toggle whether these fields are
|
||||
displayed or not.
|
||||
* Added a ':mark' command to bookmark the top line in the current view.
|
||||
* Added an ':alt-msg' command that can be used to set the text to be
|
||||
displayed in the bottom right of the command line. This command is
|
||||
mostly intended for use by hotkey maps to set the help text.
|
||||
* In lnav scripts, the first row of a SQL query result will now be turned
|
||||
into local variables that can be referenced in other commands or
|
||||
queries. For example, the following script will print the number one:
|
||||
;SELECT 1 as foobar
|
||||
:eval :echo ${foobar}
|
||||
* Added an 'lnav_view_stack' SQL table that gives access to the view
|
||||
stack.
|
||||
* Added a 'top_time' column to the lnav_views table so that you can get
|
||||
the timestamp for the top line in views that are time-based as well as
|
||||
allowing you to move the view to a given time with an UPDATE statement.
|
||||
* Added a 'search' column to the lnav_views table so that you can perform
|
||||
a text search programmatically.
|
||||
* Added a 'regexp_capture(<string>, <pattern>)' table-valued function for
|
||||
getting detailed results from matching a regular expression against a
|
||||
string.
|
||||
* Added a 'timediff(<time1>, <time2>)' SQL function for computing the
|
||||
difference between two relative or absolute timestamps.
|
||||
* Log formats can now define a default set of highlights with the
|
||||
"highlights" property.
|
||||
* Added a '|search-for <pattern>' built-in script that can be used to
|
||||
start a search from the command-line.
|
||||
* Log format definitions can now specify the expected log level for a
|
||||
sample line. This check should make it easier to validate the
|
||||
definition.
|
||||
|
||||
Interface Changes:
|
||||
* Command and SQL documentation is now displayed in a section at the
|
||||
bottom of the screen when a command or query is being entered. Some
|
||||
commands will also display a preview of the command results. For
|
||||
example, the ':open' command will display the first ten lines of the
|
||||
file to be opened and the ':filter-out' command will highlight text
|
||||
that matches in the current view. The preview pane can be shown/hidden
|
||||
by pressing CTRL-P.
|
||||
* The color used for text colored via ":highlight" is now based on the
|
||||
the regex instead of randomly picked so that colors are consistent
|
||||
across invocations.
|
||||
* The "graph" view has been removed since it's functionality has been
|
||||
obsoleted by other features, like ":create-search-table".
|
||||
* When doing a search, if a hit is found within a second after hitting
|
||||
<ENTER>, the view will move to the matched line. The previous behavior
|
||||
was to stay on the current line, which tended to be a surprise to new
|
||||
users.
|
||||
* Pressing 'n'/'N' to move through the next/previous search hit will now
|
||||
skip adjacent lines, up to the vertical size of the view. This should
|
||||
make scanning through clusters of hits much faster. Repeatedly
|
||||
pressing these keys within a short time will also accelerate scanning
|
||||
by moving the view at least a full page at a time.
|
||||
|
||||
Breaking Changes:
|
||||
* The captured timestamp text in log files must fully match a known format
|
||||
or an error will be reported. The previous behavior was to ignore any
|
||||
text at the end of the line.
|
||||
|
||||
Fixes:
|
||||
* You can now execute commands from the standard input by using a dash (-)
|
||||
with the '-f' command-line argument. Reading commands from a file
|
||||
descriptor should also work, for example, with the following bash
|
||||
syntax:
|
||||
|
||||
$ lnav -f <(echo :open the-file-to-open)
|
||||
* Programming language syntax highlighting should now only be applied to
|
||||
source code files instead of everywhere.
|
||||
|
||||
lnav v0.8.1:
|
||||
Features:
|
||||
* Added a spectrogram command and view that displays the values of a
|
||||
numeric field over time. The view works for log message fields or
|
||||
for database result columns.
|
||||
* Log formats can now create SQL views and execute other statements
|
||||
by adding '.sql' files to their format directories. The SQL scripts
|
||||
will be executed on startup.
|
||||
* Added 'json_group_object' and 'json_group_array' aggregate SQL
|
||||
functions that collects values from a GROUP BY query into a JSON
|
||||
object or array, respectively.
|
||||
* The SQL view will now graph values found in JSON objects/arrays in
|
||||
addition to the regular columns in the result.
|
||||
* Added an 'regexp_match(<re>, <str>)' SQL function that can be used to
|
||||
extract values from a string using a regular expression.
|
||||
* Added an 'extract(<str>)' SQL function that extracts values using the
|
||||
same data discover/extraction parser used in the 'logline' table.
|
||||
* Added a "summary" overlay line to the bottom of the log view that
|
||||
displays how long ago the last message was received, along with the
|
||||
total number of files and the error rate over the past five minutes.
|
||||
* Pressing 'V' in the DB view will now check for a column with a
|
||||
timestamp and move to the corresponding time in the log view.
|
||||
* Added 'a/A' hotkeys to restore a view previously popped with 'q/Q'.
|
||||
* Added ":hide-lines-before", ":hide-lines-after", and
|
||||
":show-lines-before-and-after" commands so that you can filter out
|
||||
log lines based on time.
|
||||
* Scripts containing lnav commands/queries can now be executed using
|
||||
the pipe ('|') hotkey. See the documentation for more information.
|
||||
* Added an ":eval" command that can be used to execute a command or
|
||||
query after performing environment variable substitution.
|
||||
* Added an ":echo" command that can be useful for scripts to message
|
||||
the user.
|
||||
* The "log_part" column can now be set with an SQL UPDATE statement.
|
||||
* Added a "log_body" hidden column that returns the body of the log
|
||||
message.
|
||||
* Added ":config", ":reset-config", and ":save-config" commands to change
|
||||
configuration options, reset to default, and save them for future
|
||||
executions.
|
||||
* Added a "/ui/clock-format" configuration option that controls the time
|
||||
format in the top-left corner.
|
||||
* Added a "/ui/dim-text" configuration option that controls the brightness
|
||||
of text in the UI.
|
||||
* Added support for TAI64 timestamps (http://cr.yp.to/libtai/tai64.html).
|
||||
* Added a safe execution mode. If the 'LNAVSECURE' environment variable is
|
||||
set before executing lnav, the following commands are disabled:
|
||||
- open
|
||||
- pipe-to
|
||||
- pipe-line-to
|
||||
- write-*-to
|
||||
This makes it easier to run lnav with escalated privileges in restricted
|
||||
environments, without the risk of users being able to use the above
|
||||
mentioned commands to gain privileged access.
|
||||
|
||||
Interface Changes:
|
||||
* The 'o/O' hotkeys have been reassigned to navigate through log
|
||||
messages that have a matching "opid" field. The old action of
|
||||
moving forward and backward by 60 minutes can be simulated by
|
||||
using the ':goto' command with a relative time and the 'r/R'
|
||||
hotkeys.
|
||||
* Log messages with timestamps that pre-date previous log messages will
|
||||
have the timestamp highlighted in yellow and underlined. These out-
|
||||
of-time-order messages will be assigned the time of the previous
|
||||
message for sorting purposes. You can press the 'p' hotkey to examine
|
||||
the 'Received Time' of the message as well as the time parsed from the
|
||||
original message. A "log_actual_time" hidden field has also been
|
||||
added to the SQLite virtual table so you can operate on the original
|
||||
message time from the file.
|
||||
* The 'A/B' hotkeys for moving forward/backward by 10% line increments
|
||||
have been reassigned to '[' and ']'. The 'a' and 'A' hotkeys are now
|
||||
used to return to the previously popped view while trying to preserve
|
||||
the time range. For example, after leaving the spectrogram view with
|
||||
'q', you can press 'A' return to the view with the top time in the
|
||||
spectrogram matching the top time in the log view.
|
||||
* The 'Q' hotkey now pops the current view off of the stack while
|
||||
maintaining the top time between views.
|
||||
|
||||
Fixes:
|
||||
* Issues with tailing JSON logs have been fixed.
|
||||
* The jget() SQL function should now work for objects nested in arrays.
|
||||
|
||||
lnav v0.8.0:
|
||||
Features:
|
||||
* Integration with "papertrailapp.com" for querying and tailing
|
||||
server log and syslog messages. See the Papertrail section in
|
||||
the online help for more details.
|
||||
* Remote files can be opened when lnav is built with libcurl v7.23.0+
|
||||
* SQL queries can now be done on lines that match a regular expression
|
||||
using the "log_search" table or by creating custom tables with the
|
||||
":create-search-table" command.
|
||||
* Log formats that are "containers" for other log formats, like
|
||||
syslog, are now supported. See the online help for more
|
||||
information.
|
||||
* Formats can be installed from git repositories using the '-i' option.
|
||||
A standard set of extra formats can be installed by doing
|
||||
'lnav -i extra'. (You must have git installed for this to work.)
|
||||
* Added support for 'VMware vSphere Auto Deploy' log format.
|
||||
* Added a 'sudo' log format.
|
||||
* Added hotkeys to move left/right by a smaller increment (H/L or
|
||||
Shift+Left/Shift+Right).
|
||||
* A color-coded bar has been added to the left side to show where
|
||||
messages from one file stop and messages from another file start.
|
||||
* The '-C' option will now try to check any specified log files to
|
||||
make sure the format(s) match all of the lines.
|
||||
* Added an "all_logs" SQLite table that contains the message format
|
||||
extracted from each log line. Also added a ';.msgformat' SQL command
|
||||
that executes a query that returns the counts for each format and the
|
||||
first line where the format was seen.
|
||||
* Added an "lnav_views" SQLite table that can be used to query and
|
||||
change the lnav view state.
|
||||
* When typing in a command, the status bar will display a short
|
||||
summary of the currently entered command.
|
||||
* Added a "delete-filter" command.
|
||||
* Added a "log_msg_instance" column to the logline and log_search
|
||||
tables to make it easier to join tables that are matching log
|
||||
messages that are ordered.
|
||||
* Added a "timeslice()" function to SQLite so that it is easier to
|
||||
group log messages by time buckets.
|
||||
* The 'goto' command now supports relative time values like
|
||||
'a minute ago', 'an hour later', and many more.
|
||||
|
||||
Interface Changes:
|
||||
* The 'r/R' hotkeys have been reassigned to navigate through the log
|
||||
messages by the relative time value that was last used with the
|
||||
'goto' command.
|
||||
|
||||
Fixes:
|
||||
* The pretty-print view should now work for text files.
|
||||
* Nested fields in JSON logs are now supported for levels, bodies, etc...
|
||||
* Tab-completion should work for quoted SQL identifiers.
|
||||
* 'lo-fi' mode key shortcut changed to CTRL+L.
|
||||
* 'redraw' shortcut removed. Relegated to just a command.
|
||||
* Fixed lnav hang in pretty-print mode while doing a dns lookup.
|
||||
* The generic log message parser used to extract data has been
|
||||
optimized and should be a bit faster.
|
||||
|
||||
lnav v0.7.3:
|
||||
Features:
|
||||
* Add 'pipe-to' and 'pipe-line-to' commands that pipe the currently
|
||||
marked lines or the current log message to a shell command,
|
||||
respectively.
|
||||
* Added a "pretty-print" view (P hotkey) that tries to reformat log
|
||||
messages so that they are easier to read.
|
||||
* Added a 'redraw' command (CTRL+L hotkey) to redraw the window in
|
||||
case it has been corrupted.
|
||||
* Added a 'relative-goto' command to move the current view relative
|
||||
to its current position.
|
||||
* Experimental support for linking with jemalloc.
|
||||
* The plain text view now supports filtering.
|
||||
* Added 'next-mark' and 'prev-mark' commands to jump to the next or
|
||||
previous bookmarked line (e.g. error, warning, ...)
|
||||
* Added a 'zoom-to' command to change the zoom level of the histogram
|
||||
view.
|
||||
* Log formats can now define their own timestamp formats with the
|
||||
'timestamp-format' field.
|
||||
|
||||
Fixes:
|
||||
* Autotools scripts overhaul.
|
||||
* Added a configure option to disable linking with libtinfo. The newer
|
||||
versions of ncurses don't require it, however the build silently pulls
|
||||
it in as a dependency, if it is available on the system. This can be
|
||||
explicitly disabled using the '--disable-tinfo' option during configure.
|
||||
* Fixed the configure script behavior to ignore the values specified using
|
||||
the CFLAGS and LDFLAGS environment variables while searching for sqlite3
|
||||
when '--with-sqlite3' switch was specified without the prefix.
|
||||
* The configure script now recognizes libeditline symlink'ed to masquerade
|
||||
as libreadline. This previously used to cause problems at compile time,
|
||||
specially on OS X. If you come across this error, use the
|
||||
'--with-readline=prefix' switch to specify the path to the correct
|
||||
location of libreadline.
|
||||
* The order that log formats are tried against a log file is now
|
||||
automatically determined so that more specific formats are tested
|
||||
before more general ones. The order is determined on startup based on
|
||||
how each format matches each other formats sample lines.
|
||||
* Command files (i.e. those executed via the '-f' flag) now support
|
||||
commands/queries that span more than one line.
|
||||
* Added more log levels: stats, debug2 - debug5.
|
||||
|
||||
lnav v0.7.2:
|
||||
* Added log formats for vdsm, openstack, and the vmkernel.
|
||||
* Added a "lo-fi" mode (L hotkey) that dumps the displayed log lines
|
||||
to the terminal without any decorations. The write-to, write-json-to,
|
||||
and write-csv-to commands will also write their output to the terminal
|
||||
when passed '-' as the file name. This mode can be useful for copying
|
||||
plain text lines to the clipboard.
|
||||
* (OS X) Text search strings are copied to the system's "find" clipboard.
|
||||
Also, when starting a new search, the current value in the "find"
|
||||
clipboard can be tab-completed.
|
||||
|
||||
lnav v0.7.1:
|
||||
Features:
|
||||
* Added an 'environ' SQL table that reflects lnav's environment
|
||||
variables. The table can be read and written to using SQL
|
||||
SELECT, INSERT, UPDATE, and DELETE statements. Setting variables
|
||||
can be a way to use SQL query results in lnav commands.
|
||||
* Added a 'jget' SQLite function that can extract fields from a JSON-
|
||||
encoded value.
|
||||
* Added log formats for the OpenAM identity provider.
|
||||
* Added a 'clear-highlight' command to clear previous calls to the
|
||||
'highlight' command.
|
||||
* Fixed some performance bugs in indexing JSON log formats. Loading
|
||||
times should be at least five times faster.
|
||||
* Filtering performance should be improved so that enabling/disabling
|
||||
filters should be almost instantaneous.
|
||||
* The filter-in, filter-out, and highlight commands now support
|
||||
tab-completion of text in the current view.
|
||||
* Add a '-i' flag that installs format files in: ~/.lnav/formats/installed
|
||||
|
||||
lnav v0.7.0:
|
||||
Features:
|
||||
* Add the '.schema' SQL command to open a view that displays the schema
|
||||
for the internal tables and any attached databases. If lnav was only
|
||||
executed with a SQLite database and no text files, this view will open
|
||||
by default.
|
||||
* The scroll bar now indicates the location of errors/warnings, search
|
||||
hits, and bookmarks.
|
||||
* The xterm title is update to reflect the file name for the top line
|
||||
in the view.
|
||||
* Added a "headless" mode so that you can execute commands and run SQL
|
||||
queries from the command-line without having to do it from the curses
|
||||
UI.
|
||||
* When doing a search or SQL query, any text that is currently being
|
||||
displayed can be tab-completed.
|
||||
* The '-H' option was added so you can view the internal help text.
|
||||
* Added the 'g/G' hotkeys to move to the top/bottom of the file.
|
||||
* Added a 'log_mark' column to the log tables that indicates whether or
|
||||
not a log message is bookmarked. The field is writable, so you can
|
||||
bookmark lines using an SQL UPDATE query.
|
||||
* Added syntax-highlighting when editing SQL queries or search regexes.
|
||||
* Added a "write-json-to" command that writes the result of a SQL query
|
||||
to a JSON-formatted file.
|
||||
* The "elapsed time" column now uses red/green coloring to indicate
|
||||
sharp changes in the message rate.
|
||||
* Added a "set-min-log-level" command to filter out log messages that
|
||||
are below a given level.
|
||||
|
||||
Fixes:
|
||||
* Performance improvements.
|
||||
* Multi-line filtering has been fixed.
|
||||
* A collator has been added to the log_level column in the log tables
|
||||
so that you can write expressions like "log_level > 'warning'".
|
||||
* The log_time datetime format now matches what is returned by
|
||||
"datetime('now')" so that collating works correctly.
|
||||
* If a search string is not valid PCRE syntax, a search is done for
|
||||
the exact string instead of just returning an error.
|
||||
* Static-linking has been cleaned up.
|
||||
* OpenSSL is no longer a requirement.
|
||||
* Alpha support for Windows/cygwin.
|
||||
* Environment variables can now be accessed in SQL queries using
|
||||
the syntax: $VAR_NAME
|
||||
* An internal log is kept and written out on a crash.
|
||||
* Partition bookmarks are now tracked separately from regular user
|
||||
bookmarks. You can start a partition with the 'partition-name'
|
||||
command and remove it with the 'clear-partition' command.
|
||||
* Improved display of possible matches during tab-completion in the
|
||||
command-prompt. The matches are now shown in a separate view and
|
||||
pressing tab repeatedly will scroll through the view.
|
||||
* The "open" command now does shell word expansion for file names.
|
||||
* More config directory paths have been added: /etc/lnav,
|
||||
$prefix/etc/lnav, and directories passed on the command-line with -I.
|
||||
|
||||
lnav v0.6.2:
|
||||
Features:
|
||||
* Word-wrap support.
|
||||
|
||||
Fixes:
|
||||
* Fix some OS X Mavericks build/runtime issues.
|
||||
|
||||
lnav v0.6.1:
|
||||
Features:
|
||||
* Support for JSON-encoded log files.
|
||||
|
||||
Fixes:
|
||||
* Some minor fixes and performance improvements.
|
||||
|
||||
lnav v0.6.0:
|
||||
Features:
|
||||
* Custom log formats and more builtin formats
|
||||
* Automatic extraction of data from logs
|
||||
* UI improvements, support for 256 color terminals
|
||||
|
||||
lnav v0.5.1:
|
||||
Features:
|
||||
* Added the '-t' and '-w' options which can be used to prepend a
|
||||
timestamp to any data piped in on stdin and to specify a file to
|
||||
write the contents of stdin to.
|
||||
|
||||
Fixes:
|
||||
* Cleanup for packaging.
|
||||
|
||||
lnav v0.5.0:
|
||||
Features:
|
||||
* Files can be specified on the command-line using wildcards so that
|
||||
new files are automatically loaded. Directories can also be passed
|
||||
as command-line arguments to read all of the files in the directory.
|
||||
* Builds on cygwin again.
|
||||
* Added the 'C' hotkey to clear any existing user bookmarks.
|
||||
* Added experimental support for accepting input from mice.
|
||||
|
||||
Fixes:
|
||||
* Internal cleanup.
|
||||
* Copying to the clipboard on OS X is now supported.
|
||||
* Many bug fixes.
|
||||
|
||||
lnav v0.4.0:
|
||||
Features:
|
||||
* Files that are not recognized as containing log messages have been
|
||||
broken out to a separate text files view. You can flip between the
|
||||
log view and the text file view with the 't' hotkey. When viewing
|
||||
text files, the 'f' hotkey will switch between files.
|
||||
* Files compressed with bzip2 are recognized and decompressed on the
|
||||
fly.
|
||||
* Added a "session" file and command for storing commands that should
|
||||
be executed on startup. For example, if you always want some
|
||||
highlighting to be done, you can add that command to the session
|
||||
file.
|
||||
|
||||
Fixes:
|
||||
* Add some more log file formats for generic log files.
|
||||
* Performance improvements for compressed files.
|
||||
* Works on OS X now.
|
||||
|
||||
lnav v0.3.0:
|
||||
Changes:
|
||||
* The hotkey for the SQL view was changed to 'v' and 'V' from '.'.
|
||||
|
||||
Features:
|
||||
* You can now switch between the SQL result view and the log view while
|
||||
keeping the top of the views in sync with the "log_line" column.
|
||||
|
||||
Fixes:
|
||||
* The "log_line" column is no longer included in the SQL result view's
|
||||
stacked bar graph.
|
||||
* Added a "warnings" count to the histogram view.
|
12
README
|
@ -15,10 +15,10 @@ efficiently zero in on problems.
|
|||
PREREQUISITES
|
||||
-------------
|
||||
|
||||
The following software packages are required to build lnav:
|
||||
The following software packages are required to build/run lnav:
|
||||
|
||||
gcc/clang - A C++14-compatible compiler.
|
||||
libpcre - The Perl Compatible Regular Expression (PCRE) library.
|
||||
libpcre2 - The Perl Compatible Regular Expression v2 (PCRE2) library.
|
||||
sqlite - The SQLite database engine. Version 3.9.0 or higher is required.
|
||||
ncurses - The ncurses text UI library.
|
||||
readline - The readline line editing library.
|
||||
|
@ -27,6 +27,8 @@ The following software packages are required to build lnav:
|
|||
re2c - The re2c scanner generator.
|
||||
libcurl - The cURL library for downloading files from URLs. Version
|
||||
7.23.0 or higher is required.
|
||||
libarchive - The libarchive library for opening archive files, like zip/tgz.
|
||||
wireshark - The 'tshark' program is used to interpret pcap files.
|
||||
|
||||
|
||||
INSTALLATION
|
||||
|
@ -34,6 +36,8 @@ INSTALLATION
|
|||
|
||||
Lnav follows the usual GNU style for configuring and installing software:
|
||||
|
||||
Run "./autogen.sh" if compiling from a cloned repository.
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
@ -65,7 +69,7 @@ ACKNOWLEDGEMENTS
|
|||
|
||||
The xterm color database was copied from:
|
||||
|
||||
http://jonasjacek.github.io/colors/
|
||||
https://jonasjacek.github.io/colors/
|
||||
|
||||
|
||||
SEE ALSO
|
||||
|
@ -73,4 +77,4 @@ SEE ALSO
|
|||
|
||||
The lnav website:
|
||||
|
||||
http://lnav.org
|
||||
https://lnav.org
|
||||
|
|
159
README.md
|
@ -1,104 +1,100 @@
|
|||
[![Build Status](https://travis-ci.org/tstack/lnav.png)](https://travis-ci.org/tstack/lnav)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/24wskehb7j7a65ro?svg=true)](https://ci.appveyor.com/project/tstack/lnav)
|
||||
[![Bounties](https://img.shields.io/bountysource/team/lnav/activity.svg)](https://www.bountysource.com/teams/lnav)
|
||||
[![LoC](https://tokei.rs/b1/github/tstack/lnav)](https://github.com/tstack/lnav).
|
||||
<!-- This is a comment for testing purposes -->
|
||||
|
||||
_This is the source repository for **lnav**, visit [http://lnav.org](http://lnav.org) for a high level overview._
|
||||
[![Build](https://github.com/tstack/lnav/workflows/ci-build/badge.svg)](https://github.com/tstack/lnav/actions?query=workflow%3Aci-build)
|
||||
[![Docs](https://readthedocs.org/projects/lnav/badge/?version=latest&style=plastic)](https://docs.lnav.org)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/tstack/lnav/badge.svg?branch=master)](https://coveralls.io/github/tstack/lnav?branch=master)
|
||||
[![lnav](https://snapcraft.io/lnav/badge.svg)](https://snapcraft.io/lnav)
|
||||
|
||||
[<img src="https://assets-global.website-files.com/6257adef93867e50d84d30e2/62594fddd654fc29fcc07359_cb48d2a8d4991281d7a6a95d2f58195e.svg" height="20"/>](https://discord.gg/erBPnKwz7R)
|
||||
|
||||
_This is the source repository for **lnav**, visit [https://lnav.org](https://lnav.org) for a high level overview._
|
||||
|
||||
# LNAV -- The Logfile Navigator
|
||||
|
||||
The log file navigator, lnav, is an enhanced log file viewer that
|
||||
takes advantage of any semantic information that can be gleaned from
|
||||
the files being viewed, such as timestamps and log levels. Using this
|
||||
extra semantic information, lnav can do things like interleaving
|
||||
messages from different files, generate histograms of messages over
|
||||
time, and providing hotkeys for navigating through the file. It is
|
||||
hoped that these features will allow the user to quickly and
|
||||
efficiently zero in on problems.
|
||||
The Log File Navigator, **lnav** for short, is an advanced log file viewer
|
||||
for the small-scale. It is a terminal application that can understand
|
||||
your log files and make it easy for you to find problems with little to
|
||||
no setup.
|
||||
|
||||
## Screenshot
|
||||
|
||||
## Prerequisites
|
||||
The following screenshot shows a syslog file. Log lines are displayed with
|
||||
highlights. Errors are red and warnings are yellow.
|
||||
|
||||
The following software packages are required to build lnav:
|
||||
[![Screenshot](docs/assets/images/lnav-syslog-thumb.png)](docs/assets/images/lnav-syslog.png)
|
||||
|
||||
* gcc/clang - A C++14-compatible compiler.
|
||||
* libpcre - The Perl Compatible Regular Expression (PCRE) library.
|
||||
* sqlite - The SQLite database engine. Version 3.9.0 or higher is required.
|
||||
* ncurses - The ncurses text UI library.
|
||||
* readline - The readline line editing library.
|
||||
* zlib - The zlib compression library.
|
||||
* bz2 - The bzip2 compression library.
|
||||
* libcurl - The cURL library for downloading files from URLs. Version 7.23.0 or higher is required.
|
||||
## Features
|
||||
|
||||
- Log messages from different files are collated together into a single view
|
||||
- Automatic detection of log format
|
||||
- Automatic decompression of GZip and BZip2 files
|
||||
- Filter log messages based on regular expressions
|
||||
- Use SQL to analyze your logs
|
||||
- And more...
|
||||
|
||||
## Installation
|
||||
|
||||
Lnav follows the usual GNU style for configuring and installing software:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
__Run `./autogen.sh` before running any of the above commands when
|
||||
compiling from a cloned repository.__
|
||||
|
||||
|
||||
## Cygwin users
|
||||
|
||||
It should compile fine in Cygwin.
|
||||
|
||||
Alternatively, you can get the generated binary from [AppVeyor](https://ci.appveyor.com/project/tstack/lnav) artifacts.
|
||||
|
||||
Remember that you still need the lnav dependencies under Cygwin, here is a quick way to do it:
|
||||
|
||||
setup-x86_64.exe -q -P libpcre1 -P libpcrecpp0 -P libsqlite3_0 -P libstdc++6
|
||||
|
||||
Currently, the x64 version seems to be working better than the x86 one.
|
||||
|
||||
[Download a statically-linked binary for Linux/MacOS from the release page](https://github.com/tstack/lnav/releases/latest#release-artifacts)
|
||||
|
||||
## Usage
|
||||
|
||||
The only file installed is the executable, `lnav`. You can execute it
|
||||
with no arguments to view the default set of files:
|
||||
|
||||
$ lnav
|
||||
```
|
||||
$ lnav
|
||||
```
|
||||
|
||||
You can view all the syslog messages by running:
|
||||
|
||||
$ lnav /var/log/messages*
|
||||
```
|
||||
$ lnav /var/log/messages*
|
||||
```
|
||||
|
||||
### Usage with `systemd-journald`
|
||||
|
||||
On systems running `systemd-journald`, you can use `lnav` as the pager:
|
||||
|
||||
$ journalctl | lnav
|
||||
```
|
||||
$ journalctl | lnav
|
||||
```
|
||||
|
||||
or in follow mode:
|
||||
|
||||
$ journalctl -f | lnav
|
||||
```
|
||||
$ journalctl -f | lnav
|
||||
```
|
||||
|
||||
Since `journalctl`'s default output format omits the year, if you are
|
||||
viewing logs which span multiple years you will need to change the
|
||||
output format to include the year, otherwise `lnav` gets confused:
|
||||
|
||||
$ journalctl -o short-iso | lnav
|
||||
```
|
||||
$ journalctl -o short-iso | lnav
|
||||
```
|
||||
|
||||
It is also possible to use `journalctl`'s json output format and `lnav`
|
||||
will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT:
|
||||
will make use of additional fields such as PRIORITY and \_SYSTEMD_UNIT:
|
||||
|
||||
$ journalctl -o json | lnav
|
||||
```
|
||||
$ journalctl -o json | lnav
|
||||
```
|
||||
|
||||
In case some MESSAGE fields contain special characters such as
|
||||
ANSI color codes which are considered as unprintable by journalctl,
|
||||
specifying `journalctl`'s `-a` option might be preferable in order
|
||||
to output those messages still in a non binary representation:
|
||||
to output those messages still in a non-binary representation:
|
||||
|
||||
$ journalctl -a -o json | lnav
|
||||
```
|
||||
$ journalctl -a -o json | lnav
|
||||
```
|
||||
|
||||
If using systemd v236 or newer, the output fields can be limited to
|
||||
the ones actually recognized by `lnav` for increased efficiency:
|
||||
|
||||
$ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav
|
||||
```
|
||||
$ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav
|
||||
```
|
||||
|
||||
If your system has been running for a long time, for increased
|
||||
efficiency you may want to limit the number of log lines fed into
|
||||
|
@ -107,18 +103,55 @@ efficiency you may want to limit the number of log lines fed into
|
|||
In case of a persistent journal, you may want to limit the number
|
||||
of log lines fed into `lnav` via `journalctl`'s `-b` option.
|
||||
|
||||
## Screenshot
|
||||
## Support
|
||||
|
||||
The following screenshot shows a syslog file. Log lines are displayed with
|
||||
highlights. Errors are red and warnings are yellow.
|
||||
Please file issues on this repository or use the discussions section.
|
||||
The following alternatives are also available:
|
||||
|
||||
[![Screenshot](http://tstack.github.io/lnav/lnav-syslog-thumb.png)](http://tstack.github.io/lnav/lnav-syslog.png)
|
||||
- [support@lnav.org](mailto:support@lnav.org)
|
||||
- [Discord](https://discord.gg/erBPnKwz7R)
|
||||
- [Google Groups](https://groups.google.com/g/lnav)
|
||||
|
||||
## Links
|
||||
|
||||
See Also
|
||||
--------
|
||||
- [Main Site](https://lnav.org)
|
||||
- [**Documentation**](https://docs.lnav.org) on Read the Docs
|
||||
- [Internal Architecture](ARCHITECTURE.md)
|
||||
|
||||
The lnav website can be found at:
|
||||
## Contributing
|
||||
|
||||
> [http://lnav.org](http://lnav.org)
|
||||
- [Become a Sponsor on GitHub](https://github.com/sponsors/tstack)
|
||||
|
||||
### Building From Source
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
The following software packages are required to build lnav:
|
||||
|
||||
- gcc/clang - A C++14-compatible compiler.
|
||||
- libpcre2 - The Perl Compatible Regular Expression v2 (PCRE2) library.
|
||||
- sqlite - The SQLite database engine. Version 3.9.0 or higher is required.
|
||||
- ncurses - The ncurses text UI library.
|
||||
- readline - The readline line editing library.
|
||||
- zlib - The zlib compression library.
|
||||
- bz2 - The bzip2 compression library.
|
||||
- libcurl - The cURL library for downloading files from URLs. Version 7.23.0 or higher is required.
|
||||
- libarchive - The libarchive library for opening archive files, like zip/tgz.
|
||||
- wireshark - The 'tshark' program is used to interpret pcap files.
|
||||
|
||||
#### Build
|
||||
|
||||
Lnav follows the usual GNU style for configuring and installing software:
|
||||
|
||||
Run `./autogen.sh` if compiling from a cloned repository.
|
||||
|
||||
```console
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
[Angle-grinder](https://github.com/rcoh/angle-grinder) is a tool to slice and dice log files on the command-line.
|
||||
If you're familiar with the SumoLogic query language, you might find this tool more comfortable to work with.
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
top_srcdir="@abssrcdir@"
|
||||
export top_srcdir
|
||||
|
||||
top_srcdir_parent=`dirname ${top_srcdir}`
|
||||
export top_srcdir_parent
|
||||
|
||||
srcdir="@abssrcdir@/test"
|
||||
export srcdir
|
||||
|
||||
|
@ -10,6 +13,9 @@ export srcdir
|
|||
top_builddir=`dirname $0`
|
||||
export top_builddir
|
||||
|
||||
builddir=`pwd -P`
|
||||
export builddir
|
||||
|
||||
test_dir="@abssrcdir@/test"
|
||||
export test_dir
|
||||
|
||||
|
@ -20,6 +26,15 @@ export BZIP2_SUPPORT
|
|||
BZIP2_CMD="@BZIP2_CMD@"
|
||||
export BZIP2_CMD
|
||||
|
||||
XZ_CMD="@XZ_CMD@"
|
||||
export XZ_CMD
|
||||
|
||||
TSHARK_CMD="@TSHARK_CMD@"
|
||||
export TSHARK_CMD
|
||||
|
||||
LIBARCHIVE_LIBS="@LIBARCHIVE_LIBS@"
|
||||
export LIBARCHIVE_LIBS
|
||||
|
||||
HOME="${top_builddir}/test"
|
||||
export HOME
|
||||
|
||||
|
@ -30,6 +45,8 @@ test_file_base=`basename $1`
|
|||
# The current test number for shell based tests.
|
||||
test_num=0
|
||||
|
||||
test_hash=""
|
||||
|
||||
lnav_test="${top_builddir}/src/lnav-test"
|
||||
export lnav_test
|
||||
|
||||
|
@ -45,10 +62,17 @@ export SFTP_TEST_URL
|
|||
HAVE_SQLITE3_VALUE_SUBTYPE="@HAVE_SQLITE3_VALUE_SUBTYPE@"
|
||||
export HAVE_SQLITE3_VALUE_SUBTYPE
|
||||
|
||||
HAVE_SQLITE3_ERROR_OFFSET="@HAVE_SQLITE3_ERROR_OFFSET@"
|
||||
export HAVE_SQLITE3_ERROR_OFFSET
|
||||
|
||||
## BEGIN Functions
|
||||
|
||||
LAST_TEST=""
|
||||
|
||||
LAST_CAP_TEST=()
|
||||
|
||||
has_errors=""
|
||||
|
||||
#
|
||||
# Run a test case and capture its standard out and standard err.
|
||||
#
|
||||
|
@ -61,10 +85,73 @@ LAST_TEST=""
|
|||
# run_test rktimes -V
|
||||
#
|
||||
run_test() {
|
||||
LAST_TEST="test: $@"
|
||||
printf "%s \033[0;35m=============================================================\033[0m\n" $(date -Iseconds)
|
||||
LAST_TEST=("test: $@")
|
||||
echo "${LAST_TEST[@]}"
|
||||
export test_num=`expr ${test_num} \+ 1`
|
||||
"$@" > ${test_file_base}_${test_num}.tmp 2> ${test_file_base}_${test_num}.err
|
||||
}
|
||||
|
||||
run_cap_test() {
|
||||
LAST_CAP_TEST=("test: $@")
|
||||
local full_cmd=$(echo "${LAST_CAP_TEST[@]}" | sed -e "s;${test_dir};{test_dir};g" -e "s;${top_srcdir};{top_srcdir};g")
|
||||
export test_hash=$(echo "${full_cmd}" | shasum | cut -f 1 -d ' ')
|
||||
echo "${full_cmd}" > ${test_file_base}_${test_hash}.cmd
|
||||
"$@" > ${test_file_base}_${test_hash}.out 2> ${test_file_base}_${test_hash}.err
|
||||
|
||||
sed -ibak \
|
||||
-e "s;${test_dir};{test_dir};g" \
|
||||
-e "s;${builddir};{test_dir};g" \
|
||||
-e "s;${top_srcdir};{top_srcdir};g" \
|
||||
-e "s;${top_srcdir_parent};{top_srcdir_parent};g" \
|
||||
${test_file_base}_${test_hash}.out
|
||||
echo
|
||||
printf "%s \033[0;35m=============================================================\033[0m\n" $(date -Iseconds)
|
||||
printf '\033[0;35mCommand\033[0m: %s\n' "${full_cmd}"
|
||||
printf '\033[0;32mBEGIN\033[0m %s\n' "${test_file_base}_${test_hash}.out"
|
||||
cat "${test_file_base}_${test_hash}.out"
|
||||
printf '\033[0;32mEND\033[0m %s\n' "${test_file_base}_${test_hash}.out"
|
||||
if test -f ${srcdir}/expected/${test_file_base}_${test_hash}.out; then
|
||||
diff -w -u \
|
||||
${srcdir}/expected/${test_file_base}_${test_hash}.out \
|
||||
${test_file_base}_${test_hash}.out \
|
||||
> ${test_file_base}_${test_hash}.diff
|
||||
if test $? -ne 0; then
|
||||
echo OUT: "${full_cmd}"
|
||||
cat ${test_file_base}_${test_hash}.diff
|
||||
echo "FAIL! EXPECTED OUT DIFF"
|
||||
export has_errors="yes"
|
||||
fi
|
||||
else
|
||||
echo "FAIL! EXPECTED OUT MISSING -- ${srcdir}/expected/${test_file_base}_${test_hash}.out"
|
||||
export has_errors="yes"
|
||||
fi
|
||||
|
||||
sed -ibak -E \
|
||||
-e "s;${test_dir};{test_dir};g" \
|
||||
-e "s;${builddir};{builddir};g" \
|
||||
-e "s;${top_srcdir};{top_srcdir};g" \
|
||||
-e 's;"errorId":".+";;g' \
|
||||
${test_file_base}_${test_hash}.err
|
||||
printf '\033[0;31mBEGIN\033[0m %s\n' "${test_file_base}_${test_hash}.err"
|
||||
cat "${test_file_base}_${test_hash}.err"
|
||||
printf '\033[0;31mEND\033[0m %s\n' "${test_file_base}_${test_hash}.err"
|
||||
if test -f ${srcdir}/expected/${test_file_base}_${test_hash}.err; then
|
||||
diff -w -u ${srcdir}/expected/${test_file_base}_${test_hash}.err \
|
||||
${test_file_base}_${test_hash}.err \
|
||||
> ${test_file_base}_${test_hash}.err.diff
|
||||
if test $? -ne 0; then
|
||||
echo ERR: "${full_cmd}"
|
||||
cat ${test_file_base}_${test_hash}.err.diff
|
||||
echo "FAIL! EXPECTED ERR DIFF"
|
||||
export has_errors="yes"
|
||||
fi
|
||||
else
|
||||
echo "FAIL! EXPECTED ERR MISSING"
|
||||
export has_errors="yes"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Check the output generated by a run_test() call.
|
||||
#
|
||||
|
@ -81,25 +168,31 @@ run_test() {
|
|||
# EOF
|
||||
#
|
||||
check_output() {
|
||||
sed -ibak \
|
||||
-e "s;${test_dir};{test_dir};g" \
|
||||
-e "s;${top_srcdir};{top_srcdir};g" \
|
||||
${test_file_base}_${test_num}.tmp
|
||||
diff -w -u - ${test_file_base}_${test_num}.tmp > ${test_file_base}_${test_num}.diff
|
||||
if test $? -ne 0; then
|
||||
echo $LAST_TEST
|
||||
echo "${LAST_TEST[@]}"
|
||||
echo $1
|
||||
cat ${test_file_base}_${test_num}.diff
|
||||
exit 1
|
||||
fi
|
||||
test_num=`expr ${test_num} \+ 1`
|
||||
}
|
||||
|
||||
check_output_ws() {
|
||||
diff -u - ${test_file_base}_${test_num}.tmp > ${test_file_base}_${test_num}.diff
|
||||
if test $? -ne 0; then
|
||||
echo $LAST_TEST
|
||||
echo "${LAST_TEST[@]}"
|
||||
echo $1
|
||||
cat ${test_file_base}_${test_num}.diff
|
||||
exit 1
|
||||
fi
|
||||
test_num=`expr ${test_num} \+ 1`
|
||||
}
|
||||
|
||||
test_filename() {
|
||||
echo ${test_file_base}_${test_num}.tmp
|
||||
}
|
||||
|
||||
test_err_filename() {
|
||||
|
@ -107,10 +200,14 @@ test_err_filename() {
|
|||
}
|
||||
|
||||
check_error_output() {
|
||||
sed -ibak \
|
||||
-e "s;${test_dir};{test_dir};g" \
|
||||
-e "s;${top_srcdir};{top_srcdir};g" \
|
||||
${test_file_base}_${test_num}.err
|
||||
diff -w -u - ${test_file_base}_${test_num}.err \
|
||||
> ${test_file_base}_${test_num}.err.diff
|
||||
if test $? -ne 0; then
|
||||
echo $LAST_TEST
|
||||
echo "${LAST_TEST[@]}"
|
||||
echo $1
|
||||
cat ${test_file_base}_${test_num}.err.diff
|
||||
exit 1
|
||||
|
@ -120,7 +217,7 @@ check_error_output() {
|
|||
#
|
||||
# Grep for a string in the output generated by a run_test() call.
|
||||
#
|
||||
# Usage: grep_output_for <string> <fail maessage>
|
||||
# Usage: grep_output_for <string> <fail message>
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
|
@ -137,12 +234,21 @@ grep_output_for() {
|
|||
echo "${test_file_base}_${test_num}.tmp: $2"
|
||||
exit 1
|
||||
fi
|
||||
test_num=`expr ${test_num} \+ 1`
|
||||
}
|
||||
|
||||
on_error_log() {
|
||||
if test $? -ne 0; then
|
||||
echo $1 > /dev/stderr
|
||||
cat ${test_file_base}_${test_num}.tmp
|
||||
cat ${test_file_base}_${test_num}.err
|
||||
fi
|
||||
}
|
||||
|
||||
on_error_fail_with() {
|
||||
if test $? -ne 0; then
|
||||
echo $1 > /dev/stderr
|
||||
cat ${test_file_base}_${test_num}.tmp
|
||||
cat ${test_file_base}_${test_num}.err
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
@ -159,3 +265,11 @@ else
|
|||
shift
|
||||
. ${test_file}
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
if test "${has_errors}"x = "yes"x; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
trap "cleanup" EXIT
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
version: "{build}"
|
||||
image: Visual Studio 2022
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
|
@ -8,7 +9,7 @@ environment:
|
|||
cygsetup: setup-x86_64.exe
|
||||
|
||||
install:
|
||||
- C:\%cygwin%\%cygsetup% -qnNdO -R C:/%cygwin% -s http://cygwin.mirror.constant.com -l C:/%cygwin%/var/cache/setup -P libpcre-devel -P libncurses-devel -P libreadline-devel -P zlib-devel -P libbz2-devel -P libsqlite3-devel
|
||||
- C:\%cygwin%\%cygsetup% -qnNdOX -R C:/%cygwin% -l C:/%cygwin%/var/cache/setup -P libpcre2-devel -P libncurses-devel -P libreadline-devel -P zlib-devel -P libbz2-devel -P libsqlite3-devel -P libcurl-devel -P libarchive-devel
|
||||
|
||||
build_script:
|
||||
- C:\%cygwin%\bin\sh -lc "uname -a && gcc --version && cd /cygdrive/c/projects/lnav && ./autogen.sh && ./configure && make && strip src/lnav.exe && ldd src/lnav.exe"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
srcdir="$1"
|
||||
builddir="$2"
|
||||
|
||||
for fname in "${srcdir}"/expected/*.out; do
|
||||
stem=$(basename "$fname" | sed -e 's/.out$//')
|
||||
|
||||
if ! test -f "${builddir}/$stem.cmd"; then
|
||||
echo "removing $fname"
|
||||
guilt rm "$fname"
|
||||
echo "removing ${srcdir}/expected/${stem}.err"
|
||||
guilt rm "${srcdir}/expected/${stem}.err"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,438 @@
|
|||
# Copyright (c) 2012 - 2017, Lars Bilke
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# CHANGES:
|
||||
#
|
||||
# 2012-01-31, Lars Bilke
|
||||
# - Enable Code Coverage
|
||||
#
|
||||
# 2013-09-17, Joakim Söderberg
|
||||
# - Added support for Clang.
|
||||
# - Some additional usage instructions.
|
||||
#
|
||||
# 2016-02-03, Lars Bilke
|
||||
# - Refactored functions to use named parameters
|
||||
#
|
||||
# 2017-06-02, Lars Bilke
|
||||
# - Merged with modified version from github.com/ufz/ogs
|
||||
#
|
||||
# 2019-05-06, Anatolii Kurotych
|
||||
# - Remove unnecessary --coverage flag
|
||||
#
|
||||
# 2019-12-13, FeRD (Frank Dana)
|
||||
# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor
|
||||
# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments.
|
||||
# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY
|
||||
# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list
|
||||
# - Set lcov basedir with -b argument
|
||||
# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be
|
||||
# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().)
|
||||
# - Delete output dir, .info file on 'make clean'
|
||||
# - Remove Python detection, since version mismatches will break gcovr
|
||||
# - Minor cleanup (lowercase function names, update examples...)
|
||||
#
|
||||
# 2019-12-19, FeRD (Frank Dana)
|
||||
# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets
|
||||
#
|
||||
# 2020-01-19, Bob Apthorpe
|
||||
# - Added gfortran support
|
||||
#
|
||||
# 2020-02-17, FeRD (Frank Dana)
|
||||
# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters
|
||||
# in EXCLUDEs, and remove manual escaping from gcovr targets
|
||||
#
|
||||
# USAGE:
|
||||
#
|
||||
# 1. Copy this file into your cmake modules path.
|
||||
#
|
||||
# 2. Add the following line to your CMakeLists.txt (best inside an if-condition
|
||||
# using a CMake option() to enable it just optionally):
|
||||
# include(CodeCoverage)
|
||||
#
|
||||
# 3. Append necessary compiler flags:
|
||||
# append_coverage_compiler_flags()
|
||||
#
|
||||
# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og
|
||||
#
|
||||
# 4. If you need to exclude additional directories from the report, specify them
|
||||
# using full paths in the COVERAGE_EXCLUDES variable before calling
|
||||
# setup_target_for_coverage_*().
|
||||
# Example:
|
||||
# set(COVERAGE_EXCLUDES
|
||||
# '${PROJECT_SOURCE_DIR}/src/dir1/*'
|
||||
# '/path/to/my/src/dir2/*')
|
||||
# Or, use the EXCLUDE argument to setup_target_for_coverage_*().
|
||||
# Example:
|
||||
# setup_target_for_coverage_lcov(
|
||||
# NAME coverage
|
||||
# EXECUTABLE testrunner
|
||||
# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*")
|
||||
#
|
||||
# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set
|
||||
# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR)
|
||||
# Example:
|
||||
# set(COVERAGE_EXCLUDES "dir1/*")
|
||||
# setup_target_for_coverage_gcovr_html(
|
||||
# NAME coverage
|
||||
# EXECUTABLE testrunner
|
||||
# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src"
|
||||
# EXCLUDE "dir2/*")
|
||||
#
|
||||
# 5. Use the functions described below to create a custom make target which
|
||||
# runs your test executable and produces a code coverage report.
|
||||
#
|
||||
# 6. Build a Debug build:
|
||||
# cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
# make
|
||||
# make my_coverage_target
|
||||
#
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
# Check prereqs
|
||||
find_program( GCOV_PATH gcov )
|
||||
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
|
||||
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
|
||||
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
||||
find_program( CPPFILT_PATH NAMES c++filt )
|
||||
|
||||
if(NOT GCOV_PATH)
|
||||
message(FATAL_ERROR "gcov not found! Aborting...")
|
||||
endif() # NOT GCOV_PATH
|
||||
|
||||
message("foo ${CMAKE_CXX_COMPILER_ID}")
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
|
||||
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
|
||||
endif()
|
||||
elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
|
||||
if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "[Ff]lang")
|
||||
# Do nothing; exit conditional without error if true
|
||||
elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
|
||||
# Do nothing; exit conditional without error if true
|
||||
else()
|
||||
message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(COVERAGE_COMPILER_FLAGS "-g -fprofile-arcs -ftest-coverage"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_Fortran_FLAGS_COVERAGE
|
||||
${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the Fortran compiler during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE
|
||||
${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the C++ compiler during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_C_FLAGS_COVERAGE
|
||||
${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the C compiler during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
""
|
||||
CACHE STRING "Flags used for linking binaries during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||
""
|
||||
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
|
||||
FORCE )
|
||||
mark_as_advanced(
|
||||
CMAKE_Fortran_FLAGS_COVERAGE
|
||||
CMAKE_CXX_FLAGS_COVERAGE
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
|
||||
endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
|
||||
link_libraries(gcov)
|
||||
endif()
|
||||
|
||||
# Defines a target for running and collection code coverage information
|
||||
# Builds dependencies, runs the given executable and outputs reports.
|
||||
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||
# the coverage generation will not complete.
|
||||
#
|
||||
# setup_target_for_coverage_lcov(
|
||||
# NAME testrunner_coverage # New target name
|
||||
# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES testrunner # Dependencies to build first
|
||||
# BASE_DIRECTORY "../" # Base directory for report
|
||||
# # (defaults to PROJECT_SOURCE_DIR)
|
||||
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
|
||||
# # to BASE_DIRECTORY, with CMake 3.4+)
|
||||
# NO_DEMANGLE # Don't demangle C++ symbols
|
||||
# # even if c++filt is found
|
||||
# )
|
||||
function(setup_target_for_coverage_lcov)
|
||||
|
||||
set(options NO_DEMANGLE)
|
||||
set(oneValueArgs BASE_DIRECTORY NAME)
|
||||
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT LCOV_PATH)
|
||||
message(FATAL_ERROR "lcov not found! Aborting...")
|
||||
endif() # NOT LCOV_PATH
|
||||
|
||||
if(NOT GENHTML_PATH)
|
||||
message(FATAL_ERROR "genhtml not found! Aborting...")
|
||||
endif() # NOT GENHTML_PATH
|
||||
|
||||
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
|
||||
if(${Coverage_BASE_DIRECTORY})
|
||||
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
|
||||
else()
|
||||
set(BASEDIR ${PROJECT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
# Collect excludes (CMake 3.4+: Also compute absolute paths)
|
||||
set(LCOV_EXCLUDES "")
|
||||
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_LCOV_EXCLUDES})
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||
endif()
|
||||
list(APPEND LCOV_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES LCOV_EXCLUDES)
|
||||
|
||||
# Conditional arguments
|
||||
if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE})
|
||||
set(GENHTML_EXTRA_ARGS "--demangle-cpp")
|
||||
endif()
|
||||
|
||||
# Setup target
|
||||
add_custom_target(${Coverage_NAME}
|
||||
|
||||
# Cleanup lcov
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . -b ${BASEDIR} --zerocounters
|
||||
# Create baseline to make sure untouched files show up in the report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -b ${BASEDIR} -o ${Coverage_NAME}.base
|
||||
|
||||
# Run tests
|
||||
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
|
||||
# Capturing lcov counters and generating report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . -b ${BASEDIR} --capture --output-file ${Coverage_NAME}.capture
|
||||
# add baseline counters
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.capture --output-file ${Coverage_NAME}.total
|
||||
# filter collected data to final coverage report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove ${Coverage_NAME}.total ${LCOV_EXCLUDES} --output-file ${Coverage_NAME}.info
|
||||
|
||||
# Generate HTML output
|
||||
COMMAND ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o ${Coverage_NAME} ${Coverage_NAME}.info
|
||||
|
||||
# Set output files as GENERATED (will be removed on 'make clean')
|
||||
BYPRODUCTS
|
||||
${Coverage_NAME}.base
|
||||
${Coverage_NAME}.capture
|
||||
${Coverage_NAME}.total
|
||||
${Coverage_NAME}.info
|
||||
${Coverage_NAME} # report directory
|
||||
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
VERBATIM # Protect arguments to commands
|
||||
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
|
||||
)
|
||||
|
||||
# Show where to find the lcov info report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
endfunction() # setup_target_for_coverage_lcov
|
||||
|
||||
# Defines a target for running and collection code coverage information
|
||||
# Builds dependencies, runs the given executable and outputs reports.
|
||||
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||
# the coverage generation will not complete.
|
||||
#
|
||||
# setup_target_for_coverage_gcovr_xml(
|
||||
# NAME ctest_coverage # New target name
|
||||
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES executable_target # Dependencies to build first
|
||||
# BASE_DIRECTORY "../" # Base directory for report
|
||||
# # (defaults to PROJECT_SOURCE_DIR)
|
||||
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
|
||||
# # to BASE_DIRECTORY, with CMake 3.4+)
|
||||
# )
|
||||
function(setup_target_for_coverage_gcovr_xml)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs BASE_DIRECTORY NAME)
|
||||
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
endif() # NOT GCOVR_PATH
|
||||
|
||||
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
|
||||
if(${Coverage_BASE_DIRECTORY})
|
||||
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
|
||||
else()
|
||||
set(BASEDIR ${PROJECT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
# Collect excludes (CMake 3.4+: Also compute absolute paths)
|
||||
set(GCOVR_EXCLUDES "")
|
||||
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||
endif()
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
|
||||
|
||||
# Combine excludes to several -e arguments
|
||||
set(GCOVR_EXCLUDE_ARGS "")
|
||||
foreach(EXCLUDE ${GCOVR_EXCLUDES})
|
||||
list(APPEND GCOVR_EXCLUDE_ARGS "-e")
|
||||
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${Coverage_NAME}
|
||||
# Run tests
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH} --xml
|
||||
-r ${BASEDIR} ${GCOVR_EXCLUDE_ARGS}
|
||||
--object-directory=${PROJECT_BINARY_DIR}
|
||||
-o ${Coverage_NAME}.xml
|
||||
BYPRODUCTS ${Coverage_NAME}.xml
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
VERBATIM # Protect arguments to commands
|
||||
COMMENT "Running gcovr to produce Cobertura code coverage report."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml."
|
||||
)
|
||||
endfunction() # setup_target_for_coverage_gcovr_xml
|
||||
|
||||
# Defines a target for running and collection code coverage information
|
||||
# Builds dependencies, runs the given executable and outputs reports.
|
||||
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||
# the coverage generation will not complete.
|
||||
#
|
||||
# setup_target_for_coverage_gcovr_html(
|
||||
# NAME ctest_coverage # New target name
|
||||
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES executable_target # Dependencies to build first
|
||||
# BASE_DIRECTORY "../" # Base directory for report
|
||||
# # (defaults to PROJECT_SOURCE_DIR)
|
||||
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
|
||||
# # to BASE_DIRECTORY, with CMake 3.4+)
|
||||
# )
|
||||
function(setup_target_for_coverage_gcovr_html)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs BASE_DIRECTORY NAME)
|
||||
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
endif() # NOT GCOVR_PATH
|
||||
|
||||
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
|
||||
if(${Coverage_BASE_DIRECTORY})
|
||||
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
|
||||
else()
|
||||
set(BASEDIR ${PROJECT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
# Collect excludes (CMake 3.4+: Also compute absolute paths)
|
||||
set(GCOVR_EXCLUDES "")
|
||||
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||
endif()
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
|
||||
|
||||
# Combine excludes to several -e arguments
|
||||
set(GCOVR_EXCLUDE_ARGS "")
|
||||
foreach(EXCLUDE ${GCOVR_EXCLUDES})
|
||||
list(APPEND GCOVR_EXCLUDE_ARGS "-e")
|
||||
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${Coverage_NAME}
|
||||
# Run tests
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
|
||||
# Create folder
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
|
||||
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH} --html --html-details
|
||||
-r ${BASEDIR} ${GCOVR_EXCLUDE_ARGS}
|
||||
--object-directory=${PROJECT_BINARY_DIR}
|
||||
-o ${Coverage_NAME}/index.html
|
||||
|
||||
BYPRODUCTS ${PROJECT_BINARY_DIR}/${Coverage_NAME} # report directory
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
VERBATIM # Protect arguments to commands
|
||||
COMMENT "Running gcovr to produce HTML code coverage report."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
endfunction() # setup_target_for_coverage_gcovr_html
|
||||
|
||||
function(append_coverage_compiler_flags)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||
message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
|
||||
endfunction() # append_coverage_compiler_flags
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
hunter_config(
|
||||
libpcre
|
||||
VERSION 8.41
|
||||
CMAKE_ARGS
|
||||
EXTRA_FLAGS=--enable-unicode-properties --enable-jit --enable-utf
|
||||
)
|
||||
|
||||
hunter_config(
|
||||
readline
|
||||
VERSION 6.3
|
||||
CMAKE_ARGS
|
||||
EXTRA_FLAGS=CFLAGS=-Wno-implicit-function-declaration
|
||||
)
|
|
@ -0,0 +1,528 @@
|
|||
# Copyright (c) 2013-2019, Ruslan Baratov
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# This is a gate file to Hunter package manager.
|
||||
# Include this file using `include` command and add package you need, example:
|
||||
#
|
||||
# cmake_minimum_required(VERSION 3.2)
|
||||
#
|
||||
# include("cmake/HunterGate.cmake")
|
||||
# HunterGate(
|
||||
# URL "https://github.com/path/to/hunter/archive.tar.gz"
|
||||
# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
|
||||
# )
|
||||
#
|
||||
# project(MyProject)
|
||||
#
|
||||
# hunter_add_package(Foo)
|
||||
# hunter_add_package(Boo COMPONENTS Bar Baz)
|
||||
#
|
||||
# Projects:
|
||||
# * https://github.com/hunter-packages/gate/
|
||||
# * https://github.com/ruslo/hunter
|
||||
|
||||
option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
|
||||
|
||||
if(HUNTER_ENABLED)
|
||||
if(CMAKE_VERSION VERSION_LESS "3.2")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"At least CMake version 3.2 required for Hunter dependency management."
|
||||
" Update CMake or set HUNTER_ENABLED to OFF."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(CMakeParseArguments) # cmake_parse_arguments
|
||||
|
||||
option(HUNTER_STATUS_PRINT "Print working status" ON)
|
||||
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
|
||||
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
|
||||
|
||||
set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors")
|
||||
|
||||
function(hunter_gate_status_print)
|
||||
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
|
||||
foreach(print_message ${ARGV})
|
||||
message(STATUS "[hunter] ${print_message}")
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_status_debug)
|
||||
if(HUNTER_STATUS_DEBUG)
|
||||
foreach(print_message ${ARGV})
|
||||
string(TIMESTAMP timestamp)
|
||||
message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_error_page error_page)
|
||||
message("------------------------------ ERROR ------------------------------")
|
||||
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html")
|
||||
message("-------------------------------------------------------------------")
|
||||
message("")
|
||||
message(FATAL_ERROR "")
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_internal_error)
|
||||
message("")
|
||||
foreach(print_message ${ARGV})
|
||||
message("[hunter ** INTERNAL **] ${print_message}")
|
||||
endforeach()
|
||||
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
|
||||
message("")
|
||||
hunter_gate_error_page("error.internal")
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_fatal_error)
|
||||
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}")
|
||||
if("${hunter_ERROR_PAGE}" STREQUAL "")
|
||||
hunter_gate_internal_error("Expected ERROR_PAGE")
|
||||
endif()
|
||||
message("")
|
||||
foreach(x ${hunter_UNPARSED_ARGUMENTS})
|
||||
message("[hunter ** FATAL ERROR **] ${x}")
|
||||
endforeach()
|
||||
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
|
||||
message("")
|
||||
hunter_gate_error_page("${hunter_ERROR_PAGE}")
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_user_error)
|
||||
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data")
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_self root version sha1 result)
|
||||
string(COMPARE EQUAL "${root}" "" is_bad)
|
||||
if(is_bad)
|
||||
hunter_gate_internal_error("root is empty")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${version}" "" is_bad)
|
||||
if(is_bad)
|
||||
hunter_gate_internal_error("version is empty")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${sha1}" "" is_bad)
|
||||
if(is_bad)
|
||||
hunter_gate_internal_error("sha1 is empty")
|
||||
endif()
|
||||
|
||||
string(SUBSTRING "${sha1}" 0 7 archive_id)
|
||||
|
||||
set(
|
||||
hunter_self
|
||||
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
|
||||
)
|
||||
|
||||
set("${result}" "${hunter_self}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Set HUNTER_GATE_ROOT cmake variable to suitable value.
|
||||
function(hunter_gate_detect_root)
|
||||
# Check CMake variable
|
||||
string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
|
||||
if(not_empty)
|
||||
set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
|
||||
hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check environment variable
|
||||
string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
|
||||
if(not_empty)
|
||||
set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
|
||||
hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check HOME environment variable
|
||||
string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
|
||||
if(result)
|
||||
set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
|
||||
hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
|
||||
if(WIN32)
|
||||
string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
|
||||
if(result)
|
||||
set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
|
||||
hunter_gate_status_debug(
|
||||
"HUNTER_ROOT set using SYSTEMDRIVE environment variable"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
|
||||
if(result)
|
||||
set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
|
||||
hunter_gate_status_debug(
|
||||
"HUNTER_ROOT set using USERPROFILE environment variable"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
hunter_gate_fatal_error(
|
||||
"Can't detect HUNTER_ROOT"
|
||||
ERROR_PAGE "error.detect.hunter.root"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(hunter_gate_download dir)
|
||||
string(
|
||||
COMPARE
|
||||
NOTEQUAL
|
||||
"$ENV{HUNTER_DISABLE_AUTOINSTALL}"
|
||||
""
|
||||
disable_autoinstall
|
||||
)
|
||||
if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
|
||||
hunter_gate_fatal_error(
|
||||
"Hunter not found in '${dir}'"
|
||||
"Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
|
||||
"Settings:"
|
||||
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
|
||||
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
|
||||
ERROR_PAGE "error.run.install"
|
||||
)
|
||||
endif()
|
||||
string(COMPARE EQUAL "${dir}" "" is_bad)
|
||||
if(is_bad)
|
||||
hunter_gate_internal_error("Empty 'dir' argument")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
|
||||
if(is_bad)
|
||||
hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
|
||||
if(is_bad)
|
||||
hunter_gate_internal_error("HUNTER_GATE_URL empty")
|
||||
endif()
|
||||
|
||||
set(done_location "${dir}/DONE")
|
||||
set(sha1_location "${dir}/SHA1")
|
||||
|
||||
set(build_dir "${dir}/Build")
|
||||
set(cmakelists "${dir}/CMakeLists.txt")
|
||||
|
||||
hunter_gate_status_debug("Locking directory: ${dir}")
|
||||
file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
|
||||
hunter_gate_status_debug("Lock done")
|
||||
|
||||
if(EXISTS "${done_location}")
|
||||
# while waiting for lock other instance can do all the job
|
||||
hunter_gate_status_debug("File '${done_location}' found, skip install")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(REMOVE_RECURSE "${build_dir}")
|
||||
file(REMOVE_RECURSE "${cmakelists}")
|
||||
|
||||
file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
|
||||
|
||||
# Disabling languages speeds up a little bit, reduces noise in the output
|
||||
# and avoids path too long windows error
|
||||
file(
|
||||
WRITE
|
||||
"${cmakelists}"
|
||||
"cmake_minimum_required(VERSION 3.2)\n"
|
||||
"project(HunterDownload LANGUAGES NONE)\n"
|
||||
"include(ExternalProject)\n"
|
||||
"ExternalProject_Add(\n"
|
||||
" Hunter\n"
|
||||
" URL\n"
|
||||
" \"${HUNTER_GATE_URL}\"\n"
|
||||
" URL_HASH\n"
|
||||
" SHA1=${HUNTER_GATE_SHA1}\n"
|
||||
" DOWNLOAD_DIR\n"
|
||||
" \"${dir}\"\n"
|
||||
" TLS_VERIFY\n"
|
||||
" ${HUNTER_TLS_VERIFY}\n"
|
||||
" SOURCE_DIR\n"
|
||||
" \"${dir}/Unpacked\"\n"
|
||||
" CONFIGURE_COMMAND\n"
|
||||
" \"\"\n"
|
||||
" BUILD_COMMAND\n"
|
||||
" \"\"\n"
|
||||
" INSTALL_COMMAND\n"
|
||||
" \"\"\n"
|
||||
")\n"
|
||||
)
|
||||
|
||||
if(HUNTER_STATUS_DEBUG)
|
||||
set(logging_params "")
|
||||
else()
|
||||
set(logging_params OUTPUT_QUIET)
|
||||
endif()
|
||||
|
||||
hunter_gate_status_debug("Run generate")
|
||||
|
||||
# Need to add toolchain file too.
|
||||
# Otherwise on Visual Studio + MDD this will fail with error:
|
||||
# "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
|
||||
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
|
||||
get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
|
||||
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
|
||||
else()
|
||||
# 'toolchain_arg' can't be empty
|
||||
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
|
||||
if(no_make)
|
||||
set(make_arg "")
|
||||
else()
|
||||
# Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
|
||||
set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}"
|
||||
"-H${dir}"
|
||||
"-B${build_dir}"
|
||||
"-G${CMAKE_GENERATOR}"
|
||||
"${toolchain_arg}"
|
||||
${make_arg}
|
||||
WORKING_DIRECTORY "${dir}"
|
||||
RESULT_VARIABLE download_result
|
||||
${logging_params}
|
||||
)
|
||||
|
||||
if(NOT download_result EQUAL 0)
|
||||
hunter_gate_internal_error(
|
||||
"Configure project failed."
|
||||
"To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}"
|
||||
"In directory ${dir}"
|
||||
)
|
||||
endif()
|
||||
|
||||
hunter_gate_status_print(
|
||||
"Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
|
||||
" ${HUNTER_GATE_URL}"
|
||||
" -> ${dir}"
|
||||
)
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
|
||||
WORKING_DIRECTORY "${dir}"
|
||||
RESULT_VARIABLE download_result
|
||||
${logging_params}
|
||||
)
|
||||
|
||||
if(NOT download_result EQUAL 0)
|
||||
hunter_gate_internal_error("Build project failed")
|
||||
endif()
|
||||
|
||||
file(REMOVE_RECURSE "${build_dir}")
|
||||
file(REMOVE_RECURSE "${cmakelists}")
|
||||
|
||||
file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
|
||||
file(WRITE "${done_location}" "DONE")
|
||||
|
||||
hunter_gate_status_debug("Finished")
|
||||
endfunction()
|
||||
|
||||
# Must be a macro so master file 'cmake/Hunter' can
|
||||
# apply all variables easily just by 'include' command
|
||||
# (otherwise PARENT_SCOPE magic needed)
|
||||
macro(HunterGate)
|
||||
if(HUNTER_GATE_DONE)
|
||||
# variable HUNTER_GATE_DONE set explicitly for external project
|
||||
# (see `hunter_download`)
|
||||
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
|
||||
endif()
|
||||
|
||||
# First HunterGate command will init Hunter, others will be ignored
|
||||
get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
|
||||
|
||||
if(NOT HUNTER_ENABLED)
|
||||
# Empty function to avoid error "unknown function"
|
||||
function(hunter_add_package)
|
||||
endfunction()
|
||||
|
||||
set(
|
||||
_hunter_gate_disabled_mode_dir
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
|
||||
)
|
||||
if(EXISTS "${_hunter_gate_disabled_mode_dir}")
|
||||
hunter_gate_status_debug(
|
||||
"Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
|
||||
)
|
||||
list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
|
||||
endif()
|
||||
elseif(_hunter_gate_done)
|
||||
hunter_gate_status_debug("Secondary HunterGate (use old settings)")
|
||||
hunter_gate_self(
|
||||
"${HUNTER_CACHED_ROOT}"
|
||||
"${HUNTER_VERSION}"
|
||||
"${HUNTER_SHA1}"
|
||||
_hunter_self
|
||||
)
|
||||
include("${_hunter_self}/cmake/Hunter")
|
||||
else()
|
||||
set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
|
||||
if(_have_project_name)
|
||||
hunter_gate_fatal_error(
|
||||
"Please set HunterGate *before* 'project' command. "
|
||||
"Detected project: ${PROJECT_NAME}"
|
||||
ERROR_PAGE "error.huntergate.before.project"
|
||||
)
|
||||
endif()
|
||||
|
||||
cmake_parse_arguments(
|
||||
HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
|
||||
)
|
||||
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
|
||||
string(
|
||||
COMPARE
|
||||
NOTEQUAL
|
||||
"${HUNTER_GATE_UNPARSED_ARGUMENTS}"
|
||||
""
|
||||
_have_unparsed
|
||||
)
|
||||
string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
|
||||
string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
|
||||
|
||||
if(_have_unparsed)
|
||||
hunter_gate_user_error(
|
||||
"HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
|
||||
)
|
||||
endif()
|
||||
if(_empty_sha1)
|
||||
hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
|
||||
endif()
|
||||
if(_empty_url)
|
||||
hunter_gate_user_error("URL suboption of HunterGate is mandatory")
|
||||
endif()
|
||||
if(_have_global)
|
||||
if(HUNTER_GATE_LOCAL)
|
||||
hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
|
||||
endif()
|
||||
if(_have_filepath)
|
||||
hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
|
||||
endif()
|
||||
endif()
|
||||
if(HUNTER_GATE_LOCAL)
|
||||
if(_have_global)
|
||||
hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
|
||||
endif()
|
||||
if(_have_filepath)
|
||||
hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
|
||||
endif()
|
||||
endif()
|
||||
if(_have_filepath)
|
||||
if(_have_global)
|
||||
hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
|
||||
endif()
|
||||
if(HUNTER_GATE_LOCAL)
|
||||
hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
hunter_gate_detect_root() # set HUNTER_GATE_ROOT
|
||||
|
||||
# Beautify path, fix probable problems with windows path slashes
|
||||
get_filename_component(
|
||||
HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
|
||||
)
|
||||
hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
|
||||
if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
|
||||
string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
|
||||
if(NOT _contain_spaces EQUAL -1)
|
||||
hunter_gate_fatal_error(
|
||||
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
|
||||
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
|
||||
"(Use at your own risk!)"
|
||||
ERROR_PAGE "error.spaces.in.hunter.root"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(
|
||||
REGEX
|
||||
MATCH
|
||||
"[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
|
||||
HUNTER_GATE_VERSION
|
||||
"${HUNTER_GATE_URL}"
|
||||
)
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
|
||||
if(_is_empty)
|
||||
set(HUNTER_GATE_VERSION "unknown")
|
||||
endif()
|
||||
|
||||
hunter_gate_self(
|
||||
"${HUNTER_GATE_ROOT}"
|
||||
"${HUNTER_GATE_VERSION}"
|
||||
"${HUNTER_GATE_SHA1}"
|
||||
_hunter_self
|
||||
)
|
||||
|
||||
set(_master_location "${_hunter_self}/cmake/Hunter")
|
||||
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
|
||||
set(_done_location "${_archive_id_location}/DONE")
|
||||
set(_sha1_location "${_archive_id_location}/SHA1")
|
||||
|
||||
# Check Hunter already downloaded by HunterGate
|
||||
if(NOT EXISTS "${_done_location}")
|
||||
hunter_gate_download("${_archive_id_location}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_done_location}")
|
||||
hunter_gate_internal_error("hunter_gate_download failed")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_sha1_location}")
|
||||
hunter_gate_internal_error("${_sha1_location} not found")
|
||||
endif()
|
||||
file(READ "${_sha1_location}" _sha1_value)
|
||||
string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
|
||||
if(NOT _is_equal)
|
||||
hunter_gate_internal_error(
|
||||
"Short SHA1 collision:"
|
||||
" ${_sha1_value} (from ${_sha1_location})"
|
||||
" ${HUNTER_GATE_SHA1} (HunterGate)"
|
||||
)
|
||||
endif()
|
||||
if(NOT EXISTS "${_master_location}")
|
||||
hunter_gate_user_error(
|
||||
"Master file not found:"
|
||||
" ${_master_location}"
|
||||
"try to update Hunter/HunterGate"
|
||||
)
|
||||
endif()
|
||||
include("${_master_location}")
|
||||
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
|
||||
endif()
|
||||
endmacro()
|
|
@ -0,0 +1,33 @@
|
|||
# ---- Variables ----
|
||||
|
||||
# We use variables separate from what CTest uses, because those have
|
||||
# customization issues
|
||||
set(
|
||||
COVERAGE_TRACE_COMMAND
|
||||
lcov -c -q
|
||||
-o "${PROJECT_BINARY_DIR}/coverage.info"
|
||||
-d "${PROJECT_BINARY_DIR}"
|
||||
--include "${PROJECT_SOURCE_DIR}/*"
|
||||
CACHE STRING
|
||||
"; separated command to generate a trace for the 'coverage' target"
|
||||
)
|
||||
|
||||
set(
|
||||
COVERAGE_HTML_COMMAND
|
||||
genhtml --legend -f -q
|
||||
"${PROJECT_BINARY_DIR}/coverage.info"
|
||||
-p "${PROJECT_SOURCE_DIR}"
|
||||
-o "${PROJECT_BINARY_DIR}/coverage_html"
|
||||
CACHE STRING
|
||||
"; separated command to generate an HTML report for the 'coverage' target"
|
||||
)
|
||||
|
||||
# ---- Coverage target ----
|
||||
|
||||
add_custom_target(
|
||||
coverage
|
||||
COMMAND ${COVERAGE_TRACE_COMMAND}
|
||||
COMMAND ${COVERAGE_HTML_COMMAND}
|
||||
COMMENT "Generating coverage report"
|
||||
VERBATIM
|
||||
)
|
|
@ -0,0 +1,32 @@
|
|||
include(cmake/folders.cmake)
|
||||
|
||||
include(CTest)
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
run-exe
|
||||
COMMAND lnav
|
||||
VERBATIM
|
||||
)
|
||||
add_dependencies(run-exe lnav)
|
||||
|
||||
option(BUILD_MCSS_DOCS "Build documentation using Doxygen and m.css" OFF)
|
||||
if(BUILD_MCSS_DOCS)
|
||||
include(cmake/docs.cmake)
|
||||
endif()
|
||||
|
||||
option(ENABLE_COVERAGE "Enable coverage support separate from CTest's" OFF)
|
||||
if(ENABLE_COVERAGE)
|
||||
include(cmake/coverage.cmake)
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
include(cmake/open-cpp-coverage.cmake OPTIONAL)
|
||||
endif()
|
||||
|
||||
include(cmake/lint-targets.cmake)
|
||||
include(cmake/spell-targets.cmake)
|
||||
|
||||
add_folders(Project)
|
|
@ -0,0 +1,112 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
foreach(var IN ITEMS PROJECT_BINARY_DIR PROJECT_SOURCE_DIR)
|
||||
if(NOT DEFINED "${var}")
|
||||
message(FATAL_ERROR "${var} must be defined")
|
||||
endif()
|
||||
endforeach()
|
||||
set(bin "${PROJECT_BINARY_DIR}")
|
||||
set(src "${PROJECT_SOURCE_DIR}")
|
||||
|
||||
# ---- Dependencies ----
|
||||
|
||||
set(mcss_SOURCE_DIR "${bin}/docs/.ci")
|
||||
if(NOT IS_DIRECTORY "${mcss_SOURCE_DIR}")
|
||||
file(MAKE_DIRECTORY "${mcss_SOURCE_DIR}")
|
||||
file(
|
||||
DOWNLOAD
|
||||
https://github.com/friendlyanon/m.css/releases/download/release-1/mcss.zip
|
||||
"${mcss_SOURCE_DIR}/mcss.zip"
|
||||
STATUS status
|
||||
EXPECTED_MD5 00cd2757ebafb9bcba7f5d399b3bec7f
|
||||
)
|
||||
if(NOT status MATCHES "^0;")
|
||||
message(FATAL_ERROR "Download failed with ${status}")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_COMMAND}" -E tar xf mcss.zip
|
||||
WORKING_DIRECTORY "${mcss_SOURCE_DIR}"
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
if(NOT result EQUAL "0")
|
||||
message(FATAL_ERROR "Extraction failed with ${result}")
|
||||
endif()
|
||||
file(REMOVE "${mcss_SOURCE_DIR}/mcss.zip")
|
||||
endif()
|
||||
|
||||
find_program(Python3_EXECUTABLE NAMES python3 python)
|
||||
if(NOT Python3_EXECUTABLE)
|
||||
message(FATAL_ERROR "Python executable was not found")
|
||||
endif()
|
||||
|
||||
# ---- Process project() call in CMakeLists.txt ----
|
||||
|
||||
file(READ "${src}/CMakeLists.txt" content)
|
||||
|
||||
string(FIND "${content}" "project(" index)
|
||||
if(index EQUAL "-1")
|
||||
message(FATAL_ERROR "Could not find \"project(\"")
|
||||
endif()
|
||||
string(SUBSTRING "${content}" "${index}" -1 content)
|
||||
|
||||
string(FIND "${content}" "\n)\n" index)
|
||||
if(index EQUAL "-1")
|
||||
message(FATAL_ERROR "Could not find \"\\n)\\n\"")
|
||||
endif()
|
||||
string(SUBSTRING "${content}" 0 "${index}" content)
|
||||
|
||||
file(WRITE "${bin}/docs-ci.project.cmake" "docs_${content}\n)\n")
|
||||
|
||||
macro(list_pop_front list out)
|
||||
list(GET "${list}" 0 "${out}")
|
||||
list(REMOVE_AT "${list}" 0)
|
||||
endmacro()
|
||||
|
||||
function(docs_project name)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 "" "" "VERSION;DESCRIPTION;HOMEPAGE_URL" LANGUAGES)
|
||||
set(PROJECT_NAME "${name}" PARENT_SCOPE)
|
||||
if(DEFINED _VERSION)
|
||||
set(PROJECT_VERSION "${_VERSION}" PARENT_SCOPE)
|
||||
string(REGEX MATCH "^[0-9]+(\\.[0-9]+)*" versions "${_VERSION}")
|
||||
string(REPLACE . ";" versions "${versions}")
|
||||
set(suffixes MAJOR MINOR PATCH TWEAK)
|
||||
while(NOT versions STREQUAL "" AND NOT suffixes STREQUAL "")
|
||||
list_pop_front(versions version)
|
||||
list_pop_front(suffixes suffix)
|
||||
set("PROJECT_VERSION_${suffix}" "${version}" PARENT_SCOPE)
|
||||
endwhile()
|
||||
endif()
|
||||
if(DEFINED _DESCRIPTION)
|
||||
set(PROJECT_DESCRIPTION "${_DESCRIPTION}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(DEFINED _HOMEPAGE_URL)
|
||||
set(PROJECT_HOMEPAGE_URL "${_HOMEPAGE_URL}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
include("${bin}/docs-ci.project.cmake")
|
||||
|
||||
# ---- Generate docs ----
|
||||
|
||||
if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY)
|
||||
set(DOXYGEN_OUTPUT_DIRECTORY "${bin}/docs")
|
||||
endif()
|
||||
set(out "${DOXYGEN_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(file IN ITEMS Doxyfile conf.py)
|
||||
configure_file("${src}/docs/${file}.in" "${bin}/docs/${file}" @ONLY)
|
||||
endforeach()
|
||||
|
||||
set(mcss_script "${mcss_SOURCE_DIR}/documentation/doxygen.py")
|
||||
set(config "${bin}/docs/conf.py")
|
||||
|
||||
file(REMOVE_RECURSE "${out}/html" "${out}/xml")
|
||||
|
||||
execute_process(
|
||||
COMMAND "${Python3_EXECUTABLE}" "${mcss_script}" "${config}"
|
||||
WORKING_DIRECTORY "${bin}/docs"
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
if(NOT result EQUAL "0")
|
||||
message(FATAL_ERROR "m.css returned with ${result}")
|
||||
endif()
|
|
@ -0,0 +1,46 @@
|
|||
# ---- Dependencies ----
|
||||
|
||||
set(extract_timestamps "")
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
|
||||
set(extract_timestamps DOWNLOAD_EXTRACT_TIMESTAMP YES)
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
mcss URL
|
||||
https://github.com/friendlyanon/m.css/releases/download/release-1/mcss.zip
|
||||
URL_MD5 00cd2757ebafb9bcba7f5d399b3bec7f
|
||||
SOURCE_DIR "${PROJECT_BINARY_DIR}/mcss"
|
||||
UPDATE_DISCONNECTED YES
|
||||
${extract_timestamps}
|
||||
)
|
||||
FetchContent_MakeAvailable(mcss)
|
||||
|
||||
find_package(Python3 3.6 REQUIRED)
|
||||
|
||||
# ---- Declare documentation target ----
|
||||
|
||||
set(
|
||||
DOXYGEN_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/docs"
|
||||
CACHE PATH "Path for the generated Doxygen documentation"
|
||||
)
|
||||
|
||||
set(working_dir "${PROJECT_BINARY_DIR}/docs")
|
||||
|
||||
foreach (file IN ITEMS Doxyfile conf.py)
|
||||
configure_file("docs/${file}.in" "${working_dir}/${file}" @ONLY)
|
||||
endforeach ()
|
||||
|
||||
set(mcss_script "${mcss_SOURCE_DIR}/documentation/doxygen.py")
|
||||
set(config "${working_dir}/conf.py")
|
||||
|
||||
add_custom_target(
|
||||
docs
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory
|
||||
"${DOXYGEN_OUTPUT_DIRECTORY}/html"
|
||||
"${DOXYGEN_OUTPUT_DIRECTORY}/xml"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${mcss_script}" "${config}"
|
||||
COMMENT "Building documentation using Doxygen and m.css"
|
||||
WORKING_DIRECTORY "${working_dir}"
|
||||
VERBATIM
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
set_property(GLOBAL PROPERTY USE_FOLDERS YES)
|
||||
|
||||
# Call this function at the end of a directory scope to assign a folder to
|
||||
# targets created in that directory. Utility targets will be assigned to the
|
||||
# UtilityTargets folder, otherwise to the ${name}Targets folder. If a target
|
||||
# already has a folder assigned, then that target will be skipped.
|
||||
function(add_folders name)
|
||||
get_property(targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
|
||||
foreach(target IN LISTS targets)
|
||||
get_property(folder TARGET "${target}" PROPERTY FOLDER)
|
||||
if(DEFINED folder)
|
||||
continue()
|
||||
endif()
|
||||
set(folder Utility)
|
||||
get_property(type TARGET "${target}" PROPERTY TYPE)
|
||||
if(NOT type STREQUAL "UTILITY")
|
||||
set(folder "${name}")
|
||||
endif()
|
||||
set_property(TARGET "${target}" PROPERTY FOLDER "${folder}Targets")
|
||||
endforeach()
|
||||
endfunction()
|
|
@ -0,0 +1,44 @@
|
|||
include(CMakePackageConfigHelpers)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# find_package(<package>) call for consumers to find this project
|
||||
set(package lnav)
|
||||
|
||||
install(
|
||||
TARGETS lnav
|
||||
RUNTIME COMPONENT lnav_Runtime
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${package}ConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
# Allow package maintainers to freely override the path for the configs
|
||||
set(
|
||||
lnav_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/${package}"
|
||||
CACHE PATH "CMake package config location relative to the install prefix"
|
||||
)
|
||||
mark_as_advanced(lnav_INSTALL_CMAKEDIR)
|
||||
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/${package}ConfigVersion.cmake"
|
||||
DESTINATION "${lnav_INSTALL_CMAKEDIR}"
|
||||
COMPONENT lnav_Development
|
||||
)
|
||||
|
||||
# Export variables for the install script to use
|
||||
install(CODE "
|
||||
set(lnav_NAME [[$<TARGET_FILE_NAME:lnav>]])
|
||||
set(lnav_INSTALL_CMAKEDIR [[${lnav_INSTALL_CMAKEDIR}]])
|
||||
set(CMAKE_INSTALL_BINDIR [[${CMAKE_INSTALL_BINDIR}]])
|
||||
" COMPONENT lnav_Development)
|
||||
|
||||
install(
|
||||
SCRIPT cmake/install-script.cmake
|
||||
COMPONENT lnav_Development
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
include(CPack)
|
||||
endif()
|
|
@ -0,0 +1,18 @@
|
|||
file(
|
||||
RELATIVE_PATH relative_path
|
||||
"/${lnav_INSTALL_CMAKEDIR}"
|
||||
"/${CMAKE_INSTALL_BINDIR}/${lnav_NAME}"
|
||||
)
|
||||
|
||||
get_filename_component(prefix "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
|
||||
set(config_dir "${prefix}/${lnav_INSTALL_CMAKEDIR}")
|
||||
set(config_file "${config_dir}/lnavConfig.cmake")
|
||||
|
||||
message(STATUS "Installing: ${config_file}")
|
||||
file(WRITE "${config_file}" "\
|
||||
set(
|
||||
LNAV_EXECUTABLE
|
||||
\"\${CMAKE_CURRENT_LIST_DIR}/${relative_path}\"
|
||||
CACHE FILEPATH \"Path to the lnav executable\"
|
||||
)
|
||||
")
|
|
@ -0,0 +1,32 @@
|
|||
set(
|
||||
FORMAT_PATTERNS
|
||||
src/*.cc src/*.hh
|
||||
test/*.cc test/*.hh
|
||||
CACHE STRING
|
||||
"; separated patterns relative to the project source dir to format"
|
||||
)
|
||||
|
||||
set(FORMAT_COMMAND clang-format CACHE STRING "Formatter to use")
|
||||
|
||||
add_custom_target(
|
||||
format-check
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "FORMAT_COMMAND=${FORMAT_COMMAND}"
|
||||
-D "PATTERNS=${FORMAT_PATTERNS}"
|
||||
-P "${PROJECT_SOURCE_DIR}/cmake/lint.cmake"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
COMMENT "Linting the code"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
format-fix
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "FORMAT_COMMAND=${FORMAT_COMMAND}"
|
||||
-D "PATTERNS=${FORMAT_PATTERNS}"
|
||||
-D FIX=YES
|
||||
-P "${PROJECT_SOURCE_DIR}/cmake/lint.cmake"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
COMMENT "Fixing the code"
|
||||
VERBATIM
|
||||
)
|
|
@ -0,0 +1,50 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
macro(default name)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${ARGN}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
default(FORMAT_COMMAND clang-format)
|
||||
default(
|
||||
PATTERNS
|
||||
src/*.cc src/*.hh
|
||||
test/*.cc test/*.hh
|
||||
)
|
||||
default(FIX NO)
|
||||
|
||||
set(flag --output-replacements-xml)
|
||||
set(args OUTPUT_VARIABLE output)
|
||||
if(FIX)
|
||||
set(flag -i)
|
||||
set(args "")
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE files ${PATTERNS})
|
||||
set(badly_formatted "")
|
||||
set(output "")
|
||||
string(LENGTH "${CMAKE_SOURCE_DIR}/" path_prefix_length)
|
||||
|
||||
foreach(file IN LISTS files)
|
||||
execute_process(
|
||||
COMMAND "${FORMAT_COMMAND}" --style=file "${flag}" "${file}"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE result
|
||||
${args}
|
||||
)
|
||||
if(NOT result EQUAL "0")
|
||||
message(FATAL_ERROR "'${file}': formatter returned with ${result}")
|
||||
endif()
|
||||
if(NOT FIX AND output MATCHES "\n<replacement offset")
|
||||
string(SUBSTRING "${file}" "${path_prefix_length}" -1 relative_file)
|
||||
list(APPEND badly_formatted "${relative_file}")
|
||||
endif()
|
||||
set(output "")
|
||||
endforeach()
|
||||
|
||||
if(NOT badly_formatted STREQUAL "")
|
||||
list(JOIN badly_formatted "\n" bad_list)
|
||||
message("The following files are badly formatted:\n\n${bad_list}\n")
|
||||
message(FATAL_ERROR "Run again with FIX=YES to fix these files.")
|
||||
endif()
|
|
@ -0,0 +1,31 @@
|
|||
# Example file to run OpenCppCoverage on Windows
|
||||
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(N)
|
||||
|
||||
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/opencppcoverage")
|
||||
|
||||
# Convert delimiters to Windows ones
|
||||
string(REPLACE "/" "\\" binary_dir "${PROJECT_BINARY_DIR}")
|
||||
string(REPLACE "/" "\\" source_dir "${PROJECT_SOURCE_DIR}")
|
||||
string(REPLACE "/" "\\" ctest "${CMAKE_CTEST_COMMAND}")
|
||||
|
||||
add_custom_target(
|
||||
win-cov
|
||||
COMMAND OpenCppCoverage -q
|
||||
# We want coverage from the child processes of CTest
|
||||
--cover_children
|
||||
# Subdirectory where the tests reside in the binary directory
|
||||
--modules "${binary_dir}\\test"
|
||||
# This command is for the developer, so export as html instead of cobertura
|
||||
--export_type "html:${binary_dir}\\opencppcoverage"
|
||||
# Source (not header) file locations
|
||||
--sources "${source_dir}\\source"
|
||||
--sources "${source_dir}\\test\\source"
|
||||
# Working directory for CTest, which should be the binary directory
|
||||
--working_dir "${binary_dir}"
|
||||
# OpenCppCoverage should be run only with the Debug configuration tests
|
||||
-- "${ctest}" -C Debug --output-on-failure -j "${N}"
|
||||
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
|
||||
VERBATIM
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
# ---- In-source guard ----
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"In-source builds are not supported. "
|
||||
"Please read the BUILDING document before trying to build this project. "
|
||||
"You may need to delete 'CMakeCache.txt' and 'CMakeFiles/' first."
|
||||
)
|
||||
endif()
|
|
@ -0,0 +1,6 @@
|
|||
# This variable is set by project() in CMake 3.21+
|
||||
string(
|
||||
COMPARE EQUAL
|
||||
"${CMAKE_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}"
|
||||
PROJECT_IS_TOP_LEVEL
|
||||
)
|
|
@ -0,0 +1,22 @@
|
|||
set(SPELL_COMMAND codespell CACHE STRING "Spell checker to use")
|
||||
|
||||
add_custom_target(
|
||||
spell-check
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "SPELL_COMMAND=${SPELL_COMMAND}"
|
||||
-P "${PROJECT_SOURCE_DIR}/cmake/spell.cmake"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
COMMENT "Checking spelling"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
spell-fix
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "SPELL_COMMAND=${SPELL_COMMAND}"
|
||||
-D FIX=YES
|
||||
-P "${PROJECT_SOURCE_DIR}/cmake/spell.cmake"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
COMMENT "Fixing spelling errors"
|
||||
VERBATIM
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
macro(default name)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${ARGN}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
default(SPELL_COMMAND codespell)
|
||||
default(FIX NO)
|
||||
|
||||
set(flag "")
|
||||
if(FIX)
|
||||
set(flag -w)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${SPELL_COMMAND}" ${flag}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
|
||||
if(result EQUAL "65")
|
||||
message(FATAL_ERROR "Run again with FIX=YES to fix these errors.")
|
||||
elseif(result EQUAL "64")
|
||||
message(FATAL_ERROR "Spell checker printed the usage info. Bad arguments?")
|
||||
elseif(NOT result EQUAL "0")
|
||||
message(FATAL_ERROR "Spell checker returned with ${result}")
|
||||
endif()
|
|
@ -0,0 +1,28 @@
|
|||
# ---- Developer mode ----
|
||||
|
||||
# Developer mode enables targets and code paths in the CMake scripts that are
|
||||
# only relevant for the developer(s) of lnav
|
||||
# Targets necessary to build the project must be provided unconditionally, so
|
||||
# consumers can trivially build and package the project
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
option(lnav_DEVELOPER_MODE "Enable developer mode" OFF)
|
||||
endif()
|
||||
|
||||
# ---- Warning guard ----
|
||||
|
||||
# target_include_directories with the SYSTEM modifier will request the compiler
|
||||
# to omit warnings from the provided paths, if the compiler supports that
|
||||
# This is to provide a user experience similar to find_package when
|
||||
# add_subdirectory or FetchContent is used to consume this project
|
||||
set(warning_guard "")
|
||||
if(NOT PROJECT_IS_TOP_LEVEL)
|
||||
option(
|
||||
lnav_INCLUDES_WITH_SYSTEM
|
||||
"Use SYSTEM modifier for lnav's includes, disabling warnings"
|
||||
ON
|
||||
)
|
||||
mark_as_advanced(lnav_INCLUDES_WITH_SYSTEM)
|
||||
if(lnav_INCLUDES_WITH_SYSTEM)
|
||||
set(warning_guard SYSTEM)
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,58 @@
|
|||
from conans import ConanFile
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps
|
||||
|
||||
|
||||
class LnavConan(ConanFile):
|
||||
name = "lnav"
|
||||
version = "0.11.1"
|
||||
homepage = "https://lnav.org"
|
||||
url = "https://github.com/tstack/lnav.git"
|
||||
license = "BSD-2-Clause"
|
||||
description = (
|
||||
"The Log File Navigator, lnav for short, is an advanced "
|
||||
"log file viewer for the small-scale"
|
||||
)
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
exports_sources = "*"
|
||||
no_copy_source = True
|
||||
requires = (
|
||||
"bzip2/1.0.8",
|
||||
"libarchive/3.6.0",
|
||||
"libcurl/7.85.0",
|
||||
"ncurses/6.3",
|
||||
"pcre2/10.40",
|
||||
"readline/8.1.2",
|
||||
"sqlite3/3.38.0",
|
||||
"zlib/1.2.12",
|
||||
)
|
||||
generators = ("virtualrunenv",)
|
||||
default_options = {
|
||||
"libarchive:with_bzip2": True,
|
||||
"libarchive:with_lz4": True,
|
||||
"libarchive:with_lzo": True,
|
||||
"libarchive:with_lzma": True,
|
||||
"libarchive:with_zstd": True,
|
||||
"pcre2:support_jit": True,
|
||||
"pcre2:build_pcre2_8": True,
|
||||
"sqlite3:enable_json1": True,
|
||||
"sqlite3:enable_soundex": True,
|
||||
"readline:with_library": "curses",
|
||||
}
|
||||
|
||||
def generate(self):
|
||||
CMakeToolchain(self).generate()
|
||||
CMakeDeps(self).generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
if self.settings.os == "Macos" and self.settings.arch == "armv8":
|
||||
cmake.definitions["CMAKE_SYSTEM_PROCESSOR"] = "arm64"
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
cmake = CMake(self)
|
||||
cmake.install()
|
||||
|
||||
def deploy(self):
|
||||
self.copy("*", dst="bin", src="bin")
|
138
configure.ac
|
@ -1,4 +1,4 @@
|
|||
AC_INIT([lnav],[0.8.4],[lnav@googlegroups.com],[lnav],[http://lnav.org])
|
||||
AC_INIT([lnav],[0.11.1],[lnav@googlegroups.com],[lnav],[http://lnav.org])
|
||||
AC_CONFIG_SRCDIR([src/lnav.cc])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
@ -7,35 +7,52 @@ AM_SILENT_RULES([yes])
|
|||
AC_PREFIX_DEFAULT(/usr)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AX_PROG_CC_FOR_BUILD
|
||||
|
||||
AX_PTHREAD()
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
CC="$PTHREAD_CC"
|
||||
|
||||
AC_LANG(C++)
|
||||
AX_CXX_COMPILE_STDCXX_14([noext], [mandatory])
|
||||
|
||||
for defdir in /opt/local /usr/local; do
|
||||
if test -d "$defdir/include"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$defdir/include"
|
||||
fi
|
||||
done
|
||||
AC_ARG_ENABLE(
|
||||
[system-paths],
|
||||
AS_HELP_STRING([--disable-system-paths],
|
||||
[Add extra system paths]),,[enable_system_paths=yes])
|
||||
|
||||
for defdir in /opt/local /usr/local /usr /; do
|
||||
if test x"${enable_system_paths}" != x"no"; then
|
||||
for defdir in /opt/local /usr/local; do
|
||||
if test -d "$defdir/include"; then
|
||||
echo "Adding include path: $defdir/include"
|
||||
CPPFLAGS="$CPPFLAGS -I$defdir/include"
|
||||
fi
|
||||
done
|
||||
|
||||
if test -d "$defdir/lib64"; then
|
||||
LDFLAGS="$LDFLAGS -L$defdir/lib64"
|
||||
fi
|
||||
if test -d "$defdir/lib"; then
|
||||
LDFLAGS="$LDFLAGS -L$defdir/lib"
|
||||
fi
|
||||
for defdir in /opt/local /usr/local /usr /; do
|
||||
|
||||
if test -d "$defdir/lib/x86_64-linux-gnu"; then
|
||||
LDFLAGS="$LDFLAGS -L$defdir/lib/x86_64-linux-gnu"
|
||||
fi
|
||||
done
|
||||
if test -d "$defdir/lib64"; then
|
||||
LDFLAGS="$LDFLAGS -L$defdir/lib64"
|
||||
fi
|
||||
if test -d "$defdir/lib"; then
|
||||
LDFLAGS="$LDFLAGS -L$defdir/lib"
|
||||
fi
|
||||
|
||||
if test -d "$defdir/lib/x86_64-linux-gnu"; then
|
||||
LDFLAGS="$LDFLAGS -L$defdir/lib/x86_64-linux-gnu"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Not including extra system paths"
|
||||
fi
|
||||
|
||||
dnl abssrcdir is the absolute path to the source base (regardless of where
|
||||
dnl you are building it)
|
||||
AS_CASE([x$srcdir],
|
||||
[x/*],
|
||||
AS_VAR_SET(abssrcdir, $srcdir),
|
||||
AS_VAR_SET(abssrcdir, `pwd`/$srcdir)
|
||||
AS_VAR_SET(abssrcdir, `cd $srcdir; pwd`)
|
||||
)
|
||||
|
||||
AC_SUBST(abssrcdir)
|
||||
|
@ -65,6 +82,8 @@ AC_PROG_MAKE_SET
|
|||
AC_PATH_PROG(BZIP2_CMD, [bzip2])
|
||||
AC_PATH_PROG(RE2C_CMD, [re2c])
|
||||
AM_CONDITIONAL(HAVE_RE2C, test x"$RE2C_CMD" != x"")
|
||||
AC_PATH_PROG(XZ_CMD, [xz])
|
||||
AC_PATH_PROG(TSHARK_CMD, [tshark])
|
||||
|
||||
AC_CHECK_SIZEOF(off_t)
|
||||
AC_CHECK_SIZEOF(size_t)
|
||||
|
@ -72,8 +91,8 @@ AC_CHECK_SIZEOF(size_t)
|
|||
AC_STRUCT_TIMEZONE
|
||||
|
||||
AC_ARG_ENABLE([static],
|
||||
AS_HELP_STRING([--disable-static],
|
||||
[Disable static linking]))
|
||||
AS_HELP_STRING([--enable-static],
|
||||
[Enable static linking]))
|
||||
|
||||
AC_SEARCH_LIBS(openpty, util)
|
||||
AC_SEARCH_LIBS(gzseek, z, [], [AC_MSG_ERROR([libz required to build])])
|
||||
|
@ -83,7 +102,7 @@ AC_SEARCH_LIBS(BZ2_bzopen, bz2,
|
|||
AC_SUBST(BZIP2_SUPPORT)
|
||||
AC_SEARCH_LIBS(dlopen, dl)
|
||||
AC_SEARCH_LIBS(backtrace, execinfo)
|
||||
LIBCURL_CHECK_CONFIG([], [7.23.0], [], [], [test x"${enable_static}" != x"no"])
|
||||
LIBCURL_CHECK_CONFIG([], [7.23.0], [], [AC_MSG_ERROR([libcurl required to build])], [test x"${enable_static}" = x"yes"])
|
||||
|
||||
# Sometimes, curses depends on these libraries being linked in...
|
||||
AC_ARG_ENABLE([tinfo],
|
||||
|
@ -95,7 +114,7 @@ AC_ARG_ENABLE([tinfo],
|
|||
AS_IF([test "x${enable_tinfo}" != "xno"],
|
||||
[dnl
|
||||
AC_MSG_NOTICE([Trying to link with tinfo])
|
||||
AC_SEARCH_LIBS(cur_term, tinfo,
|
||||
AC_SEARCH_LIBS(cur_term, [tinfow tinfo],
|
||||
AC_MSG_NOTICE([Linking with tinfo]),
|
||||
AC_MSG_WARN([libtinfo not found])
|
||||
)
|
||||
|
@ -117,7 +136,42 @@ AS_CASE(["$host_os"],
|
|||
)
|
||||
)
|
||||
|
||||
AC_CHECK_HEADERS(execinfo.h pty.h util.h zlib.h bzlib.h libutil.h sys/ttydefaults.h x86intrin.h)
|
||||
AC_CHECK_HEADERS(execinfo.h pty.h util.h zlib.h bzlib.h libutil.h sys/ttydefaults.h)
|
||||
|
||||
dnl Experimental SIMD features.
|
||||
AC_ARG_ENABLE([simd],
|
||||
AS_HELP_STRING([--enable-simd], [Try and enable simd optimizations]),
|
||||
[
|
||||
AS_CASE(["$enable_simd"],
|
||||
[no], [enable_simd="no"],
|
||||
[yes | ""],[enable_simd="yes"])
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
AS_IF([test "x$enable_simd" = "xyes"], [
|
||||
AC_CHECK_HEADERS(x86intrin.h)
|
||||
])
|
||||
|
||||
|
||||
AC_ARG_WITH([system_doctest],
|
||||
AS_HELP_STRING(
|
||||
[--with-system-doctest],
|
||||
[Use the system provided doctest library rather than the bundled one]
|
||||
),
|
||||
[], []
|
||||
)
|
||||
|
||||
AS_IF([test "x$with_system_doctest" = "xyes"], [
|
||||
AC_CHECK_HEADERS(doctest/doctest.h)
|
||||
AS_IF([test "x$ac_cv_header_doctest_doctest_h" != "xyes"], [
|
||||
AC_MSG_ERROR([system doctest not found])dnl
|
||||
])
|
||||
])
|
||||
AS_IF([test "x$with_system_doctest" != "xyes"], [
|
||||
CPPFLAGS="-I\$(top_srcdir)/src/third-party/doctest-root $CPPFLAGS"
|
||||
])
|
||||
|
||||
|
||||
LNAV_WITH_JEMALLOC
|
||||
|
||||
|
@ -129,9 +183,12 @@ AS_VAR_IF([ax_cv_curses],[yes],[],
|
|||
AC_MSG_ERROR([requires an X/Open-compatible Curses library with color])dnl
|
||||
)
|
||||
|
||||
AX_PATH_LIB_PCRE([], [AC_MSG_ERROR([pcre required to build])])
|
||||
AX_PATH_LIB_ARCHIVE
|
||||
AX_CHECK_PCRE2([8], [], [AC_MSG_ERROR([pcre2 is required to build])])
|
||||
AX_PATH_LIB_READLINE
|
||||
|
||||
AX_CODE_COVERAGE
|
||||
|
||||
LNAV_WITH_SQLITE3("3.9.0")
|
||||
|
||||
dnl case "$host_os" in
|
||||
|
@ -144,16 +201,22 @@ dnl esac
|
|||
|
||||
AC_DEFINE([_XOPEN_SOURCE_EXTENDED], [1], [Wide character support for ncurses])
|
||||
|
||||
AS_VAR_SET(ALL_LDFLAGS, "$SQLITE3_LDFLAGS $READLINE_LDFLAGS $LDFLAGS")
|
||||
AS_VAR_SET(ALL_LDFLAGS, "$SQLITE3_LDFLAGS $READLINE_LDFLAGS $LIBARCHIVE_LDFLAGS $LIBCURL $LDFLAGS")
|
||||
|
||||
AS_VAR_SET(static_lib_list,
|
||||
["libncurses.a libncursesw.a libreadline.a libsqlite3.a libz.a libtinfo.a"])
|
||||
["libncurses.a libncursesw.a libreadline.a libsqlite3.a libz.a libtinfo.a libtinfow.a"])
|
||||
AS_VAR_SET(static_lib_list,
|
||||
["$static_lib_list libpcre.a libpcrecpp.a libncursesw.a libbz2.a"])
|
||||
["$static_lib_list libpcre2-8.a libncursesw.a libbz2.a"])
|
||||
AS_VAR_SET(static_lib_list,
|
||||
["$static_lib_list libgpm.a libcurl.a libcrypto.a libssl.a libssh2.a"])
|
||||
AS_VAR_SET(static_lib_list,
|
||||
["$static_lib_list libnghttp2.a liblzma.a libcrypto.a libzstd.a libldap.a"])
|
||||
AS_VAR_SET(static_lib_list,
|
||||
["$static_lib_list libarchive.a libidn2.a libgssapi_krb5.a libbrotlidec-static.a"])
|
||||
AS_VAR_SET(static_lib_list,
|
||||
["$static_lib_list librtmp.a libiconv.a liblz4.a liblber.a libunistring.a"])
|
||||
|
||||
if test x"${enable_static}" != x"no"; then
|
||||
if test x"${enable_static}" = x"yes"; then
|
||||
case "$host_os" in
|
||||
darwin*)
|
||||
STATIC_LDFLAGS="$STATIC_LDFLAGS -Wl,-search_paths_first"
|
||||
|
@ -162,7 +225,9 @@ if test x"${enable_static}" != x"no"; then
|
|||
|
||||
AX_CHECK_LINK_FLAG([-static-libgcc], [STATIC_LDFLAGS="$STATIC_LDFLAGS -static-libgcc"])
|
||||
|
||||
STATIC_LDFLAGS="$STATIC_LDFLAGS -L`pwd`/src/static-libs -static-libstdc++"
|
||||
STATIC_LDFLAGS="$STATIC_LDFLAGS -L`pwd`/src/static-libs"
|
||||
AX_CHECK_LINK_FLAG([-static-libstdc++],
|
||||
[STATIC_LDFLAGS="$STATIC_LDFLAGS -static-libstdc++"])
|
||||
# This is a hack to link against static libraries instead of shared
|
||||
# so that we can build a mostly statically link exe that can
|
||||
# be downloaded and used right away. This is required for OS X and
|
||||
|
@ -241,11 +306,26 @@ AS_IF([test $? -eq 0],
|
|||
|
||||
AM_CONDITIONAL(USE_INCLUDED_YAJL, test $HAVE_LOCAL_YAJL -eq 0)
|
||||
AM_CONDITIONAL(HAVE_LIBCURL, test x"$LIBCURL" != x"")
|
||||
AM_CONDITIONAL([DISABLE_DOCUMENTATION], [ test x"$cross_compiling" != x"no" ])
|
||||
|
||||
USER_CXXFLAGS="${CXXFLAGS}"
|
||||
AC_SUBST(USER_CXXFLAGS)
|
||||
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([TESTS_ENVIRONMENT])
|
||||
AC_CONFIG_FILES([tools/Makefile])
|
||||
AC_CONFIG_FILES([src/Makefile])
|
||||
AC_CONFIG_FILES([src/base/Makefile])
|
||||
AC_CONFIG_FILES([src/formats/logfmt/Makefile])
|
||||
AC_CONFIG_FILES([src/fmtlib/Makefile])
|
||||
AC_CONFIG_FILES([src/pcrepp/Makefile])
|
||||
AC_CONFIG_FILES([src/pugixml/Makefile])
|
||||
AC_CONFIG_FILES([src/tailer/Makefile])
|
||||
AC_CONFIG_FILES([src/yajl/Makefile])
|
||||
AC_CONFIG_FILES([src/yajlpp/Makefile])
|
||||
AC_CONFIG_FILES([src/third-party/base64/lib/Makefile])
|
||||
AC_CONFIG_FILES([src/third-party/scnlib/src/Makefile])
|
||||
AC_CONFIG_FILES([test/Makefile])
|
||||
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
FROM debian:11.3-slim
|
||||
|
||||
RUN set -eux; \
|
||||
export DEBIAN_FRONTEND=noninteractive; \
|
||||
apt update; \
|
||||
apt install --yes --no-install-recommends bind9-dnsutils iputils-ping iproute2 curl ca-certificates htop wget unzip openssh-server; \
|
||||
apt clean autoclean; \
|
||||
apt autoremove --yes; \
|
||||
rm -rf /var/lib/{apt,dpkg,cache,log}/; \
|
||||
echo "Installed base utils!"
|
||||
|
||||
ADD https://github.com/tstack/lnav/releases/download/v0.11.0/lnav-0.11.0-musl-64bit.zip /
|
||||
RUN unzip lnav-0.11.0-musl-64bit.zip
|
||||
|
||||
COPY docs/tutorials tutorials
|
||||
RUN gunzip /tutorials/playground/logs/*.gz
|
||||
|
||||
RUN useradd -rm -d /home/playground -s /bin/bash playground
|
||||
RUN echo 'playground:playground' | chpasswd
|
||||
RUN passwd -d playground
|
||||
|
||||
RUN useradd -rm -d /home/tutorial1 -s /bin/bash tutorial1
|
||||
RUN echo 'tutorial1:tutorial1' | chpasswd
|
||||
RUN passwd -d tutorial1
|
||||
|
||||
USER playground
|
||||
RUN /lnav-0.11.0/lnav -nN -c ":config /ui/theme monocai"
|
||||
|
||||
USER tutorial1
|
||||
RUN /lnav-0.11.0/lnav -nN -c ":config /ui/theme monocai"
|
||||
|
||||
USER root
|
||||
|
||||
RUN echo 'Match User playground' >> /etc/ssh/sshd_config
|
||||
RUN echo 'ForceCommand env PATH=/lnav-0.11.0:$PATH /tutorials/playground/run.sh' >> /etc/ssh/sshd_config
|
||||
RUN echo 'PermitEmptyPasswords yes' >> /etc/ssh/sshd_config
|
||||
RUN echo 'Match User tutorial1' >> /etc/ssh/sshd_config
|
||||
RUN echo 'ForceCommand env PATH=/lnav-0.11.0:$PATH /tutorials/tutorial1/run.sh' >> /etc/ssh/sshd_config
|
||||
RUN echo 'PermitEmptyPasswords yes' >> /etc/ssh/sshd_config
|
||||
RUN service ssh start
|
||||
EXPOSE 22
|
||||
|
||||
CMD ["/usr/sbin/sshd", "-D"]
|
|
@ -0,0 +1,35 @@
|
|||
# fly.toml file generated for lnav-demo on 2022-08-22T10:26:28-07:00
|
||||
|
||||
app = "lnav-demo"
|
||||
kill_signal = "SIGINT"
|
||||
kill_timeout = 5
|
||||
processes = []
|
||||
|
||||
[env]
|
||||
|
||||
[experimental]
|
||||
allowed_public_ports = []
|
||||
auto_rollback = true
|
||||
|
||||
[[services]]
|
||||
http_checks = []
|
||||
internal_port = 22
|
||||
processes = ["app"]
|
||||
protocol = "tcp"
|
||||
script_checks = []
|
||||
[services.concurrency]
|
||||
hard_limit = 25
|
||||
soft_limit = 20
|
||||
type = "connections"
|
||||
|
||||
[[services.ports]]
|
||||
port = 22
|
||||
|
||||
[[services.tcp_checks]]
|
||||
grace_period = "1s"
|
||||
interval = "15s"
|
||||
restart_limit = 0
|
||||
timeout = "2s"
|
||||
|
||||
[build]
|
||||
image = "lnav-demo"
|
|
@ -0,0 +1,54 @@
|
|||
import datetime
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
MSGS = [
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
|
||||
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
|
||||
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||
]
|
||||
|
||||
GLOG_DATE_FMT = "%Y%m%d %H:%M:%S"
|
||||
|
||||
START_TIME = datetime.datetime.fromtimestamp(1490191111)
|
||||
|
||||
try:
|
||||
shutil.rmtree("/tmp/demo")
|
||||
os.makedirs("/tmp/demo")
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
PIDS = [
|
||||
"123",
|
||||
"123",
|
||||
"123",
|
||||
"121",
|
||||
"124",
|
||||
"123",
|
||||
"61456",
|
||||
"61456",
|
||||
"61457",
|
||||
]
|
||||
|
||||
LOG_LOCS = [
|
||||
"demo.cc:123",
|
||||
"demo.cc:352",
|
||||
"loader.cc:13",
|
||||
"loader.cc:552",
|
||||
"blaster.cc:352",
|
||||
"blaster.cc:112",
|
||||
"blaster.cc:6782",
|
||||
]
|
||||
|
||||
CURR_TIME = START_TIME
|
||||
for _index in range(0, int(sys.argv[1])):
|
||||
CURR_TIME += datetime.timedelta(seconds=random.randrange(1, 22))
|
||||
print("I%s.%06d %s %s] %s" % (
|
||||
CURR_TIME.strftime(GLOG_DATE_FMT),
|
||||
random.randrange(0, 100000),
|
||||
random.choice(PIDS),
|
||||
random.choice(LOG_LOCS),
|
||||
random.choice(MSGS)))
|
|
@ -0,0 +1,5 @@
|
|||
_site
|
||||
.sass-cache
|
||||
.jekyll-cache
|
||||
.jekyll-metadata
|
||||
vendor
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
layout: page
|
||||
title: Downloads
|
||||
permalink: /downloads
|
||||
---
|
||||
|
||||
The latest **stable** release is [**v{{ site.version }}**](https://github.com/tstack/lnav/releases/latest).
|
||||
|
||||
The following options are available for installing **lnav**:
|
||||
|
||||
## Linux
|
||||
|
||||
<!-- markdown-link-check-disable-next-line -->
|
||||
Download a [statically linked 64-bit binary](https://github.com/tstack/lnav/releases/download/v{{site.version}}/lnav-{{site.version}}-x86_64-linux-musl.zip).
|
||||
|
||||
Install from the [Snap Store](https://snapcraft.io/lnav):
|
||||
|
||||
```console
|
||||
$ sudo snap install lnav
|
||||
```
|
||||
|
||||
## MacOS
|
||||
|
||||
<!-- markdown-link-check-disable-next-line -->
|
||||
Download a [statically linked 64-bit binary](https://github.com/tstack/lnav/releases/download/v{{site.version}}/lnav-{{site.version}}-x86_64-macos.zip)
|
||||
|
||||
Install using [Homebrew](https://formulae.brew.sh/formula/lnav):
|
||||
|
||||
```console
|
||||
$ brew install lnav
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
<!-- markdown-link-check-disable-next-line -->
|
||||
Download the [source](https://github.com/tstack/lnav/releases/download/v{{site.version}}/lnav-{{site.version}}.tar.gz)
|
||||
and install any dependencies. The following commands will unpack the source
|
||||
tar ball, configure the build for your system, build, and then install:
|
||||
|
||||
```console
|
||||
$ tar xvfz lnav-{{site.version}}.tar.gz
|
||||
$ cd lnav-{{site.version}}
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
```
|
||||
|
||||
### GitHub
|
||||
|
||||
If you would like to contribute to the development of lnav, visit our page on
|
||||
[GitHub](https://github.com/tstack/lnav).
|
||||
|
||||
# VSCode Extension
|
||||
|
||||
The [lnav VSCode Extension](https://marketplace.visualstudio.com/items?itemName=lnav.lnav)
|
||||
can be used to add syntax highlighting to lnav scripts.
|
||||
|
||||
![Screenshot of an lnav script](/assets/images/lnav-vscode-extension.png)
|
|
@ -0,0 +1,140 @@
|
|||
---
|
||||
layout: page
|
||||
title: Features
|
||||
permalink: /features
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Single Log View
|
||||
|
||||
All log file contents are merged into a single view based on message timestamps.
|
||||
You no longer need to manually correlate timestamps across multiple windows or
|
||||
figure out the order in which to view rotated log files. The color bars on the
|
||||
left-hand side help to show which file a message belongs to.
|
||||
|
||||
![Screenshot of lnav showing messages from multiple files](/assets/images/lnav-multi-file2.png)
|
||||
|
||||
## Automatic Log Format Detection
|
||||
|
||||
The log message format is automatically determined by lnav while scanning your
|
||||
files. The following formats are built in by default:
|
||||
|
||||
* Common Web Access Log format
|
||||
* CUPS page_log
|
||||
* Syslog
|
||||
* Glog
|
||||
* VMware ESXi/vCenter Logs
|
||||
* dpkg.log
|
||||
* uwsgi
|
||||
* "Generic" - Any message that starts with a timestamp
|
||||
* Strace
|
||||
* sudo
|
||||
|
||||
GZIP'ed and BZIP2'ed files are also detected automatically and decompressed on-the-fly.
|
||||
|
||||
## Filters
|
||||
|
||||
Display only lines that match or do not match a set of regular expressions.
|
||||
Useful for removing extraneous log lines that you are not interested in.
|
||||
|
||||
## Timeline View
|
||||
|
||||
The timeline view shows a histogram of messages over time. The number of
|
||||
warnings and errors are highlighted in the display so that you can easily see
|
||||
where problems have occurred. Once you have found a period of time that is of
|
||||
interest, a key-press will take you back to the log message view at the
|
||||
corresponding time.
|
||||
|
||||
![Screenshot of timeline view](/assets/images/lnav-hist.png)
|
||||
|
||||
## Pretty-Print View
|
||||
|
||||
The pretty-print view will reformat structured data, like XML or JSON, so that
|
||||
it is easier to read. Simply press SHIFT+P in the log view to have all the
|
||||
currently displayed lines pretty-printed.
|
||||
|
||||
The following screenshot shows an XML blob with no indentation:
|
||||
|
||||
![A flat blob of XML](/assets/images/lnav-before-pretty.png)
|
||||
|
||||
After pressing SHIFT+P, the XML is pretty-printed for easier viewing:
|
||||
|
||||
![A pretty-printed blob of XML](/assets/images/lnav-after-pretty.png)
|
||||
|
||||
## Query Logs Using SQL
|
||||
|
||||
Log files are directly used as the backing for SQLite virtual tables. This
|
||||
means you can perform queries on messages without having to load the data into
|
||||
an SQL database. For example, the screenshot below shows the result of
|
||||
running the following query against an Apache access_log file:
|
||||
|
||||
```sql
|
||||
SELECT c_ip, count(*), sum(sc_bytes) AS total FROM access_log
|
||||
GROUP BY c_ip ORDER BY total DESC;
|
||||
```
|
||||
|
||||
![The results of a SQL query](/assets/images/lnav-query.png)
|
||||
|
||||
## "Live" Operation
|
||||
|
||||
Searches are done as you type; new log lines are automatically loaded and
|
||||
searched as they are added; filters apply to lines as they are loaded; and, SQL
|
||||
queries are checked for correctness as you type.
|
||||
|
||||
## Themes
|
||||
|
||||
The UI can be [customized through themes](https://lnav.readthedocs.io/en/latest/config.html#theme-definitions).
|
||||
|
||||
![Animation of the UI cycling through themes](/assets/images/lnav-theme-cycle.gif)
|
||||
|
||||
## Syntax Highlighting
|
||||
|
||||
Errors and warnings are colored in red and yellow, respectively. Highlights are
|
||||
also applied to: SQL keywords, XML tags, file and line numbers in Java
|
||||
backtraces, and quoted strings. The search and SQL query prompt are also
|
||||
highlighted as you type, making it easier to see errors and matching brackets.
|
||||
|
||||
![Animation of syntax highlighting](/assets/images/lnav-syntax-highlight.gif)
|
||||
|
||||
## Tab-completion
|
||||
|
||||
The command prompt supports tab-completion for almost all operations. For
|
||||
example, when doing a search, you can tab-complete words that are displayed on
|
||||
screen rather than having to do a copy & paste.
|
||||
|
||||
![Animation of TAB-completion](/assets/images/lnav-tab-complete.gif)
|
||||
|
||||
## Custom Keymaps
|
||||
|
||||
[Hotkeys can be customized](https://lnav.readthedocs.io/en/latest/config.html#keymap-definitions)
|
||||
to run lnav commands or scripts.
|
||||
|
||||
## Sessions
|
||||
|
||||
Session information is saved automatically and restored when you are viewing the
|
||||
same set of files. The current location in files, bookmarks, and applied filters
|
||||
are all saved as part of the session.
|
||||
|
||||
## Headless Mode
|
||||
|
||||
The log processing features of lnav can be used in scripts if you have a canned
|
||||
set of operations or queries that you want to perform regularly. You can enable
|
||||
headless mode with the '-n' switch on the command-line and then use the '-c'
|
||||
flag to specify the commands or queries you want to execute. For example, to get
|
||||
the top 10 client IP addresses from an apache access log file and write the
|
||||
results to standard out in CSV format:
|
||||
|
||||
```console
|
||||
$ lnav -n \
|
||||
-c ';SELECT c_ip, count(*) AS total FROM access_log GROUP BY c_ip ORDER BY total DESC LIMIT 10' \
|
||||
-c ':write-csv-to -' \
|
||||
access.log
|
||||
|
||||
c_ip,total
|
||||
10.208.110.176,2989570
|
||||
10.178.4.102,11183
|
||||
10.32.110.197,2020
|
||||
10.29.165.250,443
|
||||
```
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
layout: page
|
||||
title: Tutorials
|
||||
permalink: /tutorials
|
||||
---
|
||||
|
||||
These tutorials are provided to help you learn how **lnav** works
|
||||
without having to install anything. They are running on a shared
|
||||
[fly.io](https://fly.io) instance, so please be kind.
|
||||
|
||||
The tutorials are implemented using features in **lnav** and not
|
||||
built in to the code itself. The tutorial text is
|
||||
[markdown](https://docs.lnav.org/en/latest/ui.html#markdown),
|
||||
the logic is written [SQL](https://docs.lnav.org/en/latest/sqlext.html),
|
||||
and the reactions are triggered through
|
||||
[events](https://docs.lnav.org/en/latest/events.html).
|
||||
|
||||
The source for the tutorials can be found [here](https://github.com/tstack/lnav/tree/master/docs/tutorials).
|
||||
|
||||
# Tutorial 1
|
||||
|
||||
<div id="playground-box">
|
||||
<h4>Learn how to navigate an example log file using lnav:</h4>
|
||||
|
||||
<code>
|
||||
<span class="prompt">$</span>
|
||||
<a href="ssh://tutorial1@demo.lnav.org">ssh tutorial1@demo.lnav.org</a>
|
||||
</code>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Docs
|
||||
permalink: /docs
|
||||
redirect_to:
|
||||
- https://docs.lnav.org
|
||||
---
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: ChangeBlog
|
||||
layout: home
|
||||
permalink: /blog/
|
||||
---
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
permalink: /404.html
|
||||
layout: default
|
||||
---
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
.container {
|
||||
margin: 10px auto;
|
||||
max-width: 600px;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
margin: 30px 0;
|
||||
font-size: 4em;
|
||||
line-height: 1;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<h1>404</h1>
|
||||
|
||||
<p><strong>Page not found :(</strong></p>
|
||||
<p>The requested page could not be found.</p>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
lnav.org
|
|
@ -0,0 +1,32 @@
|
|||
# Configuration for Doxygen for use with CMake
|
||||
# Only options that deviate from the default are included
|
||||
# To create a new Doxyfile containing all available options, call `doxygen -g`
|
||||
|
||||
# Get Project name and version from CMake
|
||||
PROJECT_NAME = "@PROJECT_NAME@"
|
||||
PROJECT_NUMBER = "@PROJECT_VERSION@"
|
||||
|
||||
# Add sources
|
||||
INPUT = "@PROJECT_SOURCE_DIR@/README.md" "@PROJECT_SOURCE_DIR@/include" "@PROJECT_SOURCE_DIR@/source" "@PROJECT_SOURCE_DIR@/docs/pages"
|
||||
EXTRACT_ALL = YES
|
||||
RECURSIVE = YES
|
||||
OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIRECTORY@"
|
||||
|
||||
# Use the README as a main page
|
||||
USE_MDFILE_AS_MAINPAGE = "@PROJECT_SOURCE_DIR@/README.md"
|
||||
|
||||
# set relative include paths
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH = "@PROJECT_SOURCE_DIR@/include" "@PROJECT_SOURCE_DIR@"
|
||||
STRIP_FROM_INC_PATH =
|
||||
|
||||
# We use m.css to generate the html documentation, so we only need XML output
|
||||
GENERATE_XML = YES
|
||||
GENERATE_HTML = NO
|
||||
GENERATE_LATEX = NO
|
||||
XML_PROGRAMLISTING = NO
|
||||
CREATE_SUBDIRS = NO
|
||||
|
||||
# Include all directories, files and namespaces in the documentation
|
||||
# Disable to include only explicitly documented objects
|
||||
M_SHOW_UNDOCUMENTED = YES
|
|
@ -0,0 +1,31 @@
|
|||
source "https://rubygems.org"
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
# gem "jekyll", "~> 4.2.0"
|
||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||
gem "minima", "~> 2.5"
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
gem "github-pages", group: :jekyll_plugins
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
end
|
||||
|
||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
# and associated library.
|
||||
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||
gem "tzinfo", "~> 1.2"
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
|
||||
|
||||
gem "webrick", "~> 1.7"
|
|
@ -0,0 +1,270 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.5.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.11.1)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.23.6)
|
||||
concurrent-ruby (1.1.10)
|
||||
dnsruby (1.61.9)
|
||||
simpleidn (~> 0.1)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
ethon (0.15.0)
|
||||
ffi (>= 1.15.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.8.1)
|
||||
faraday (2.5.2)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-net_http (3.0.0)
|
||||
ffi (1.15.5)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
github-pages (227)
|
||||
github-pages-health-check (= 1.17.9)
|
||||
jekyll (= 3.9.2)
|
||||
jekyll-avatar (= 0.7.0)
|
||||
jekyll-coffeescript (= 1.1.1)
|
||||
jekyll-commonmark-ghpages (= 0.2.0)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.15.1)
|
||||
jekyll-gist (= 1.5.0)
|
||||
jekyll-github-metadata (= 2.13.0)
|
||||
jekyll-include-cache (= 0.2.1)
|
||||
jekyll-mentions (= 1.6.0)
|
||||
jekyll-optional-front-matter (= 0.3.2)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-readme-index (= 0.3.0)
|
||||
jekyll-redirect-from (= 0.16.0)
|
||||
jekyll-relative-links (= 0.6.1)
|
||||
jekyll-remote-theme (= 0.4.3)
|
||||
jekyll-sass-converter (= 1.5.2)
|
||||
jekyll-seo-tag (= 2.8.0)
|
||||
jekyll-sitemap (= 1.4.0)
|
||||
jekyll-swiss (= 1.0.0)
|
||||
jekyll-theme-architect (= 0.2.0)
|
||||
jekyll-theme-cayman (= 0.2.0)
|
||||
jekyll-theme-dinky (= 0.2.0)
|
||||
jekyll-theme-hacker (= 0.2.0)
|
||||
jekyll-theme-leap-day (= 0.2.0)
|
||||
jekyll-theme-merlot (= 0.2.0)
|
||||
jekyll-theme-midnight (= 0.2.0)
|
||||
jekyll-theme-minimal (= 0.2.0)
|
||||
jekyll-theme-modernist (= 0.2.0)
|
||||
jekyll-theme-primer (= 0.6.0)
|
||||
jekyll-theme-slate (= 0.2.0)
|
||||
jekyll-theme-tactile (= 0.2.0)
|
||||
jekyll-theme-time-machine (= 0.2.0)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.12.0)
|
||||
kramdown (= 2.3.2)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.3)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.13.6, < 2.0)
|
||||
rouge (= 3.26.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.17.9)
|
||||
addressable (~> 2.3)
|
||||
dnsruby (~> 1.60)
|
||||
octokit (~> 4.0)
|
||||
public_suffix (>= 3.0, < 5.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.2)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (3.9.2)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (~> 0.7)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (>= 1.17, < 3)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
rouge (>= 1.7, < 4)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-avatar (0.7.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-coffeescript (1.1.1)
|
||||
coffee-script (~> 2.2)
|
||||
coffee-script-source (~> 1.11.1)
|
||||
jekyll-commonmark (1.4.0)
|
||||
commonmarker (~> 0.22)
|
||||
jekyll-commonmark-ghpages (0.2.0)
|
||||
commonmarker (~> 0.23.4)
|
||||
jekyll (~> 3.9.0)
|
||||
jekyll-commonmark (~> 1.4.0)
|
||||
rouge (>= 2.0, < 4.0)
|
||||
jekyll-default-layout (0.1.4)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-feed (0.15.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-gist (1.5.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.13.0)
|
||||
jekyll (>= 3.4, < 5.0)
|
||||
octokit (~> 4.0, != 4.4.0)
|
||||
jekyll-include-cache (0.2.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-mentions (1.6.0)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-redirect-from (0.16.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-remote-theme (0.4.3)
|
||||
addressable (~> 2.0)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
|
||||
rubyzip (>= 1.3.0, < 3.0)
|
||||
jekyll-sass-converter (1.5.2)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.8.0)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-sitemap (1.4.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-swiss (1.0.0)
|
||||
jekyll-theme-architect (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-cayman (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-dinky (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-hacker (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-leap-day (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-merlot (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-midnight (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-minimal (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-modernist (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-primer (0.6.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-github-metadata (~> 2.9)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-slate (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-tactile (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-time-machine (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-titles-from-headings (0.5.3)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
jemoji (0.12.0)
|
||||
gemoji (~> 3.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (2.3.2)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.7.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.16.3)
|
||||
nokogiri (1.13.9-arm64-darwin)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.13.9-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (4.0.7)
|
||||
racc (1.6.0)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.5)
|
||||
rouge (3.26.0)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
safe_yaml (1.0.5)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sawyer (0.9.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (>= 0.17.3, < 3)
|
||||
simpleidn (0.2.1)
|
||||
unf (~> 0.1.4)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.10)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.8.0)
|
||||
webrick (1.7.0)
|
||||
zeitwerk (2.6.0)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin-21
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
github-pages
|
||||
minima (~> 2.5)
|
||||
tzinfo (~> 1.2)
|
||||
tzinfo-data
|
||||
wdm (~> 0.1.1)
|
||||
webrick (~> 1.7)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.20
|
|
@ -0,0 +1,4 @@
|
|||
# Docs
|
||||
|
||||
This directory contains the ReST documentation that is published to
|
||||
[docs.lnav.org](https://docs.lnav.org)
|
|
@ -0,0 +1,62 @@
|
|||
# Welcome to Jekyll!
|
||||
#
|
||||
# This config file is meant for settings that affect your whole blog, values
|
||||
# which you are expected to set up once and rarely edit after that. If you find
|
||||
# yourself editing this file very often, consider using Jekyll's data files
|
||||
# feature for the data you need to update frequently.
|
||||
#
|
||||
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
||||
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
|
||||
#
|
||||
# If you need help with YAML syntax, here are some quick references for you:
|
||||
# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
|
||||
# https://learnxinyminutes.com/docs/yaml/
|
||||
#
|
||||
# Site settings
|
||||
# These are used to personalize your new site. If you look in the HTML files,
|
||||
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
|
||||
# You can create any custom variable you would like, and they will be accessible
|
||||
# in the templates via {{ site.myvariable }}.
|
||||
|
||||
title: The Logfile Navigator
|
||||
version: 0.11.1
|
||||
email: support@lnav.org
|
||||
description: >- # this means to ignore newlines until "baseurl:"
|
||||
The Logfile Navigator, lnav for short, is an advanced log file viewer
|
||||
for the small-scale.
|
||||
# baseurl: /lnav
|
||||
# url: "http://lnav.org" # the base hostname & protocol for your site, e.g. http://example.com
|
||||
twitter_username: lnavapp
|
||||
github: tstack/lnav
|
||||
|
||||
# Build settings
|
||||
theme: minima
|
||||
plugins:
|
||||
- jekyll-feed
|
||||
- jekyll-redirect-from
|
||||
|
||||
show_excerpts: true
|
||||
|
||||
exclude:
|
||||
- source
|
||||
- tutorials
|
||||
|
||||
# Exclude from processing.
|
||||
# The following items will not be processed, by default.
|
||||
# Any item listed under the `exclude:` key here will be automatically added to
|
||||
# the internal "default list".
|
||||
#
|
||||
# Excluded items can be processed by explicitly listing the directories or
|
||||
# their entries' file path in the `include:` list.
|
||||
#
|
||||
# exclude:
|
||||
# - .sass-cache/
|
||||
# - .jekyll-cache/
|
||||
# - gemfiles/
|
||||
# - Gemfile
|
||||
# - Gemfile.lock
|
||||
# - node_modules/
|
||||
# - vendor/bundle/
|
||||
# - vendor/cache/
|
||||
# - vendor/gems/
|
||||
# - vendor/ruby/
|
|
@ -0,0 +1,121 @@
|
|||
<ul class="social-media-list">
|
||||
{%- if site.dribbble_username -%}
|
||||
<li>
|
||||
<a href="https://dribbble.com/{{ site.dribbble_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#dribbble' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.dribbble_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.facebook_username -%}
|
||||
<li>
|
||||
<a href="https://www.facebook.com/{{ site.facebook_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#facebook' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.facebook_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.flickr_username -%}
|
||||
<li>
|
||||
<a href="https://www.flickr.com/photos/{{ site.flickr_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#flickr' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.flickr_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.github_username -%}
|
||||
<li>
|
||||
<a href="https://github.com/{{ site.github_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#github' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.github_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.github -%}
|
||||
<li><a href="https://github.com/{{ site.github }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#github' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.github | escape }}</span></a></li>
|
||||
{%- endif -%}
|
||||
{%- if site.instagram_username -%}
|
||||
<li>
|
||||
<a href="https://instagram.com/{{ site.instagram_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#instagram' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.instagram_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.linkedin_username -%}
|
||||
<li>
|
||||
<a href="https://www.linkedin.com/in/{{ site.linkedin_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#linkedin' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.linkedin_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.pinterest_username -%}
|
||||
<li>
|
||||
<a href="https://www.pinterest.com/{{ site.pinterest_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#pinterest' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.pinterest_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- for mst in site.mastodon -%}{%- if mst.username and mst.instance -%}
|
||||
<li>
|
||||
<a href="https://{{ mst.instance| cgi_escape | escape}}/@{{mst.username}}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#mastodon' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ mst.username|escape }}</span></a></li>
|
||||
{%- endif -%}{%- endfor -%}
|
||||
{%- if site.twitter_username -%}
|
||||
<li>
|
||||
<a href="https://www.twitter.com/{{ site.twitter_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#twitter' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.twitter_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.youtube_username -%}
|
||||
<li>
|
||||
<a href="https://youtube.com/{{ site.youtube_username| cgi_escape | escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#youtube' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.youtube_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.googleplus_username -%}
|
||||
<li>
|
||||
<a href="https://plus.google.com/{{ site.googleplus_username| escape }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#googleplus' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span class="username">{{ site.googleplus_username| escape }}</span></a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if site.rss -%}
|
||||
<li><a href="{{ 'feed.xml' | relative_url }}">
|
||||
<svg class="svg-icon">
|
||||
<use xlink:href="{{ '/assets/minima-social-icons.svg#rss' | relative_url }}"></use>
|
||||
</svg>
|
||||
<span>{{ site.rss | escape }}</span></a></li>
|
||||
{%- endif -%}
|
||||
<li><a href="https://discord.gg/erBPnKwz7R">
|
||||
<img style="height: 1.75em"
|
||||
src="https://assets-global.website-files.com/6257adef93867e50d84d30e2/62594fdd4b264a31eafa1e5d_92ad040ed5143bfb541ea61f5c3bb18f.svg"/>
|
||||
</a></li>
|
||||
</ul>
|
||||
|
||||
<script data-goatcounter="https://lnav.goatcounter.com/count"
|
||||
async src="//gc.zgo.at/count.js"></script>
|
|
@ -0,0 +1,78 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ page.lang | default: site.lang | default: "en" }}">
|
||||
|
||||
{%- include head.html -%}
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="/assets/images/favicon.svg">
|
||||
<link rel="icon" type="image/png" href="/assets/images/favicon.png">
|
||||
|
||||
<style>
|
||||
main {
|
||||
margin: 0 50px;
|
||||
}
|
||||
|
||||
#top-description {
|
||||
font-size: xx-large;
|
||||
margin-top: 3em;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
#intro {
|
||||
font-size: x-large;
|
||||
font-weight: lighter;
|
||||
margin-top: 2em;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.dlrow {
|
||||
display: grid;
|
||||
align-items: start;
|
||||
grid-template-columns: repeat(auto-fit, minmax(22em, 1fr));
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p:before, #top-description:before {
|
||||
content: "";
|
||||
width: 6em;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
grid-auto-flow: column;
|
||||
}
|
||||
dl dt {
|
||||
font-weight: normal;
|
||||
font-size: x-large;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #8d8;
|
||||
margin: 20px 30px;
|
||||
height: 2em;
|
||||
}
|
||||
dl dd {
|
||||
margin: 0 30px 20px 30px;
|
||||
min-height: 3em;
|
||||
color: #828282;
|
||||
font-size: medium;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<a href="https://github.com/tstack/lnav">
|
||||
<img loading="lazy" width="149" style="position: absolute; z-index: 100" height="149" src="https://github.blog/wp-content/uploads/2008/12/forkme_left_green_007200.png?resize=149%2C149" class="attachment-full size-full" alt="Fork me on GitHub" data-recalc-dims="1">
|
||||
</a>
|
||||
|
||||
{%- include header.html -%}
|
||||
|
||||
<main class="page-content" aria-label="Content">
|
||||
{{ content }}
|
||||
</main>
|
||||
|
||||
{%- include footer.html -%}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Support for JSON-encoded logs in v0.6.1"
|
||||
date: 2013-09-10 00:00:00
|
||||
excerpt: Turning JSON barf into something readable.
|
||||
---
|
||||
|
||||
Making logs easily digestible by machines is becoming a concern as tools like
|
||||
elasticsearch become more popular. One of the popular strategies is to encode
|
||||
the whole log message in JSON and then write that as a single line to a file.
|
||||
For example:
|
||||
|
||||
```json
|
||||
{"time": "2013-09-04T23:55:09.274041Z", "level" : "INFO", "body" : "Hello, World!" }
|
||||
{"time": "2013-09-04T23:56:00.285224Z", "level" : "ERROR", "body" : "Something terrible has happened!", "tb": " foo.c:12\n bar.y:33" }
|
||||
```
|
||||
|
||||
Unfortunately, what is good for a machine is not so great for a human. To try to
|
||||
improve the situation, the latest release of lnav includes support for parsing
|
||||
JSON log messages and transforming them on-the-fly. The display format is
|
||||
specified in a log format configuration and can specify which fields should be
|
||||
displayed on the main message line. Any unused fields that are found in the
|
||||
message will be displayed below the main field so you don't miss anything.
|
||||
|
||||
The above log lines can be transformed using the following format configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"json_ex_log": {
|
||||
"title": "Example JSON Log",
|
||||
"description": "An example log format configuration for JSON logs",
|
||||
"json": true,
|
||||
"file-pattern": "test-log\\.json.*",
|
||||
"level-field": "level",
|
||||
"line-format": [
|
||||
{
|
||||
"field": "time"
|
||||
},
|
||||
" ",
|
||||
{
|
||||
"field": "body"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After copying this config to `~/.lnav/formats/test/format.json`, the log messages
|
||||
will look like this when viewed in lnav:
|
||||
|
||||
```
|
||||
2013-09-04T23:55:09.274041Z Hello, World!
|
||||
2013-09-04T23:56:00.285224Z Something terrible has happened!
|
||||
tb: foo.c:12
|
||||
tb: bar.y:33
|
||||
```
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Four years on GitHub"
|
||||
date: 2013-09-13 00:00:00
|
||||
excerpt: Still going strong!
|
||||
---
|
||||
|
||||
The [first commit](https://github.com/tstack/lnav/commit/b4ec432515e95e86ec9d711833b8cb34d0912546)
|
||||
to the [lnav repository](https://github.com/tstack/lnav) was four years ago
|
||||
today! I started working on lnav a couple of years before that, but this was
|
||||
its first public appearance. I still use it every day and plan to keep things
|
||||
going for years to come.
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Mini review of lnav in Linux Magazine"
|
||||
date: 2013-10-05 00:00:00
|
||||
---
|
||||
|
||||
The [October issue of Linux Magazine](http://www.linux-magazine.com/Issues/2013/155/Tool-Tips)
|
||||
has a nice review of lnav v0.5.0, the author gave it four out of five stars!
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Competing with 'tail -f'"
|
||||
date: 2013-09-10 00:00:00
|
||||
excerpt: The standard utilities are tough competition.
|
||||
---
|
||||
|
||||
Probably the toughest competition for lnav is the standard Unix utilities like
|
||||
tail, grep, less, and emacs/vim. It can be hard trying to convince people that
|
||||
these built-in commands that they've used for forever can be improved upon. The
|
||||
advanced features of lnav might even work against it since folks are expecting
|
||||
to have to learn a bunch of stuff to see any benefits.
|
||||
|
||||
The reality is that there are quite a few "passive" features in lnav that can
|
||||
provide value with no effort required by the user. For example, lnav can easily
|
||||
replace 'tail -f', it's even shorter to type! Beyond the basic task of
|
||||
displaying new lines appended to a log file, you also get to see log messages
|
||||
from multiple files interleaved, the ability to scroll backwards, syntax
|
||||
highlighting, live searching, and so on. These basic features do not have the
|
||||
same "wow" factor as executing a SQL query over data automatically extracted
|
||||
from a log file, but they're the features that get used 90% of the time.
|
||||
|
||||
Anyways, I think I'm gaining a new appreciation for marketing/sales...
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Mini-review of lnav in Linux User Magazine"
|
||||
date: 2013-09-10 00:00:00
|
||||
---
|
||||
|
||||
The german magazine, [Linux User](http://www.linux-user.de/), has a
|
||||
mini-review of lnav v0.6.0 in their
|
||||
[November issue](http://www.linux-user.de/Downloads/LUCE/2013/lu-ce_2013-11.pdf)!
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Changes To The Scrollbar"
|
||||
date: 2014-02-22 00:00:00
|
||||
excerpt: Packing more information into the right scrollbar.
|
||||
---
|
||||
|
||||
I've made some changes to the scrollbar that is shown on the right side of the
|
||||
display based on some feedback from users. The scroll area now has a single
|
||||
vertical line extending from the top to the bottom. Previously, this area would
|
||||
show log message characters and it wasn't very clear that the scroll bar
|
||||
existed. The line is colored based whether there are errors or warnings in that
|
||||
part of the log. The coloring should make it easier to see the distribution of
|
||||
errors across the whole log. Similarly, there are notches added to the left and
|
||||
right side of the line to show search hits and bookmarks, respectively. See the
|
||||
following screenshot to get an idea of what it looks like:
|
||||
|
||||
![Screenshot of the redesigned scrollbar](/assets/images/scrollbar-change-2.png)
|
||||
|
||||
These changes are currently only in the latest code from git. I'll be playing
|
||||
with things a bit more before making a release.
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
layout: post
|
||||
title: Added "lo-fi" mode
|
||||
excerpt: An alternative way to copy displayed text.
|
||||
---
|
||||
|
||||
*(This change is in v0.7.2+)*
|
||||
|
||||
Copying text to the clipboard can be done by marking lines with the
|
||||
[bookmark hotkeys](https://docs.lnav.org/en/latest/hotkeys.html#bookmarks),
|
||||
like `m`, and then pressing `c`. Commands that write to a file,
|
||||
like [`:write-csv-to`](https://docs.lnav.org/en/latest/commands.html#write-csv-to-path)
|
||||
accept `/dev/clipboard` as a way to write to the clipboard. However, if the
|
||||
native clipboard isn't supported, or you're on an SSH connection, you can
|
||||
now switch to "lo-fi" mode. In "lo-fi" mode, lnav drops out of the curses
|
||||
display and prints the raw text to the terminal. You can switch to "lo-fi"
|
||||
mode in a view by pressing `CTRL-L`. For commands, you can use a dash `-`
|
||||
to switch to "lo-fi" and print to standard out.
|
||||
|
||||
<script id="asciicast-fH4cdgugIJVcPQnSwCmTdaA7f"
|
||||
src="https://asciinema.org/a/fH4cdgugIJVcPQnSwCmTdaA7f.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Pretty-print view in v0.7.3"
|
||||
date: 2015-04-11 00:00:00
|
||||
excerpt: Automatically reformat structured data with "SHIFT+P".
|
||||
---
|
||||
|
||||
I wanted to call out the pretty-print feature in the latest release of lnav.
|
||||
This idea came from a coworker of Suresh who was having a hard time trying to
|
||||
read some unformatted XML in a log. They wanted the XML pretty-printed and were
|
||||
hoping that could be done by just piping the message to xmlpp or the like. So,
|
||||
first we implemented the 'pipe-to' and 'pipe-line-to' commands that will let you
|
||||
pipe log messages to a command and then display the result inside of lnav. That
|
||||
worked well enough, but pretty-printing is such a frequent operation that having
|
||||
to execute a command was kind of a pain. It would also be nice if it worked for
|
||||
a variety of text, like JSON or Python data. The solution we came up with was to
|
||||
leverage the existing code for parsing log messages to create a simple
|
||||
pretty-printer that should work for most data formats. Another benefit is that
|
||||
the log message does not have to be well-formed for the printer to work, any
|
||||
leading or trailing garbage shouldn't confuse things.
|
||||
|
||||
As an example, here is a screenshot of the log message with the unformatted XML
|
||||
text with word-wrapping turned on:
|
||||
|
||||
![Screenshot of raw XML](/assets/images/lnav-before-pretty.png)
|
||||
|
||||
That's not very easy to read and it's hard to figure out the structure of the
|
||||
message. Now, here is that same message after pressing SHIFT+P to switch to the
|
||||
pretty-print view of lnav:
|
||||
|
||||
![Screenshot of pretty-printed XML](/assets/images/lnav-after-pretty.png)
|
||||
|
||||
The XML text is indented nicely and the usual syntax highlighting is applied.
|
||||
Also notice that lnav will automatically try to lookup the DNS name for IP
|
||||
addresses. Overall, I think it's a major improvement over the raw view.
|
||||
|
||||
This is a pretty simple feature but I have found it quite useful in the couple
|
||||
weeks that it has been implemented. It's so useful that I'm kicking myself for
|
||||
not having thought of it before.
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
layout: post
|
||||
title: "lnav in print"
|
||||
date: 2016-03-20 00:00:00
|
||||
---
|
||||
|
||||
A [review of lnav](https://archive.org/details/Linux_User_Developer_162_2016_UK/page/n87/mode/2up)
|
||||
is in Linux User & Developer magazine issue 162:
|
||||
|
||||
![Picture of lnav story in the magazine](/assets/images/linux-user-and-dev-mag.jpeg)
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Reveal log message source file paths by pressing left-arrow"
|
||||
excerpt: Find out where log messages are coming from.
|
||||
---
|
||||
|
||||
*(This change is in v0.8.4+)*
|
||||
|
||||
If you want to know which file log messages are coming from, you can press the
|
||||
left-arrow to reveal the unique name and then press it again to reveal the
|
||||
full path.
|
||||
|
||||
<script id="asciicast-ATHHpQiHVaTVxVRkhCv4ED7wT"
|
||||
src="https://asciinema.org/a/ATHHpQiHVaTVxVRkhCv4ED7wT.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Tutorial for lnav in Linux Magazine"
|
||||
date: 2018-04-05 00:00:00
|
||||
---
|
||||
|
||||
Looks like there was an in-depth
|
||||
[tutorial on lnav in Linux Magazine](http://www.linux-magazine.com/Issues/2017/196/Tutorials-lnav).
|
||||
Unfortunately, I didn't notice until now and missed out on a hardcopy.
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Support for tagging and commenting on log messages"
|
||||
excerpt: Annotate log messages with your thoughts.
|
||||
---
|
||||
|
||||
*(This change is in v0.8.4+)*
|
||||
|
||||
If you have been wanting to add notes to log messages you might be interested
|
||||
in, the new [`:comment`](https://docs.lnav.org/en/latest/commands.html#comment-text)
|
||||
and [`:tag`](https://docs.lnav.org/en/latest/commands.html#tag-tag) commands.
|
||||
These commands add a comment or tag(s) to the top message in the log view.
|
||||
The comments and tags are saved in the session, so they will be restored
|
||||
automatically when the file is reopened. These annotations can be searched
|
||||
for using the regular search prompt and can be accessed in the
|
||||
[log tables](https://docs.lnav.org/en/latest/sqlext.html#log-tables) using the
|
||||
`log_tags` and `log_comment` columns.
|
||||
|
||||
<script id="asciicast-yRTcQd2VMv3QZVs5597OyAAxI"
|
||||
src="https://asciinema.org/a/yRTcQd2VMv3QZVs5597OyAAxI.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Visual filter editor"
|
||||
excerpt: A friendlier way to interact with filters.
|
||||
---
|
||||
|
||||
*(This change is in v0.8.5+)*
|
||||
|
||||
A visual filter editor has been added to make it easier to create, edit,
|
||||
enable, disable, and delete filters. In the log or text views, pressing `TAB`
|
||||
will open the filter editor panel. While the panel is in focus, the following
|
||||
hotkeys can be used:
|
||||
|
||||
- `i` - Create an IN filter that will only show lines that match the given
|
||||
regular expression.
|
||||
- `o` - Create an OUT filter that will hide lines that match the given regular
|
||||
expression.
|
||||
- `Space` - Toggle the filter between being enabled and disabled.
|
||||
- `Enter` - Edit the selected filter.
|
||||
- `Shift+D` - Delete the filter.
|
||||
- `t` - Switch a filter from an IN to an OUT or vice-versa.
|
||||
- `f` - Globally enable or disable filtering.
|
||||
|
||||
When editing a filter, the main view will highlight lines that portion of the
|
||||
lines that match the given regular expression:
|
||||
|
||||
- Lines that match an OUT filter are highlighted with red;
|
||||
- Lines that match an IN filter are highlighted with green.
|
||||
|
||||
You can also press `TAB` to complete words that are visible in the main view.
|
||||
|
||||
<script id="asciicast-tcHeLbqVImRVcxWTYIrm3v6bw"
|
||||
src="https://asciinema.org/a/tcHeLbqVImRVcxWTYIrm3v6bw.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
layout: post
|
||||
title: Support for Themes
|
||||
excerpt: Change the user-interface to your liking
|
||||
---
|
||||
|
||||
*(This change is in v0.9.0+)*
|
||||
|
||||
The lnav user-interface can now be customized by selecting one of the
|
||||
builtin themes, like
|
||||
[monocai](https://github.com/tstack/lnav/blob/master/src/themes/monocai.json)
|
||||
and
|
||||
[night-owl](https://github.com/tstack/lnav/blob/master/src/themes/night-owl.json),
|
||||
or
|
||||
[by defining your own theme](https://lnav.readthedocs.io/en/latest/config.html#theme-definitions).
|
||||
|
||||
Selecting a theme can be done through the
|
||||
[`:config`](https://docs.lnav.org/en/latest/commands.html#config-option-value)
|
||||
command, like so:
|
||||
|
||||
```
|
||||
:config /ui/theme monocai
|
||||
```
|
||||
|
||||
Pressing `TAB` after the `/ui/theme ` will cycle through the available themes,
|
||||
like so:
|
||||
|
||||
![Animation of lnav cycling through themes](/assets/images/lnav-theme-cycle.gif)
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
layout: post
|
||||
title: Drilling down into XML snippets
|
||||
excerpt: The new "xpath()" table-valued SQL function.
|
||||
---
|
||||
|
||||
*(This change is in [**v0.10.0+**](https://github.com/tstack/lnav/releases/tag/v0.10.0))*
|
||||
|
||||
XML snippets in log messages can now be queried using the
|
||||
[`xpath()`](https://docs.lnav.org/en/latest/sqlext.html#xpath-xpath-xmldoc)
|
||||
table-valued SQL function. The function takes an
|
||||
[XPath](https://developer.mozilla.org/en-US/docs/Web/XPath), the XML snippet
|
||||
to be queried, and returns a table with the results of the XPath query.
|
||||
For example, given following XML document:
|
||||
|
||||
```xml
|
||||
<msg>Hello, World!</msg>
|
||||
```
|
||||
|
||||
Extracting the text value from the `msg` node can be done using the following
|
||||
query:
|
||||
|
||||
```sql
|
||||
SELECT result FROM xpath('/msg/text()', '<msg>Hello, World!</msg>')
|
||||
```
|
||||
|
||||
Of course, you won't typically be passing XML values as string literals, you
|
||||
will be extracting them from log messages. Assuming your log format already
|
||||
extracts the XML data, you can do a `SELECT` on the log format table and join
|
||||
that with the `xpath()` call. Since it can be challenging to construct a
|
||||
correct `xpath()` call, lnav will suggest calls for the nodes it finds in any
|
||||
XML log message fields. The following asciicast demonstrates this flow:
|
||||
|
||||
<script id="asciicast-x89mrk8JPHBmB4pTbaZvTt8Do"
|
||||
src="https://asciinema.org/a/x89mrk8JPHBmB4pTbaZvTt8Do.js"
|
||||
async>
|
||||
</script>
|
||||
|
||||
The implementation uses the [pugixml](https://pugixml.org) library.
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
layout: post
|
||||
title: Tailing files on remote hosts
|
||||
excerpt: Native support for tailing logs on machines accessible via SSH
|
||||
---
|
||||
|
||||
*(This change is in [**v0.10.0+**](https://github.com/tstack/lnav/releases/tag/v0.10.0))*
|
||||
|
||||
One of the new features in the upcoming v0.10.0 release of lnav is support
|
||||
for tailing log files on remote hosts via SSH. This feature allows you to
|
||||
view local files and files from multiple remote hosts alongside each other
|
||||
in the log view. The only setup required is to ensure the machines can be
|
||||
accessed via SSH without any interaction, meaning the host key must have
|
||||
been previously accepted and public key authentication configured. Opening
|
||||
a remote file is then simply a matter of specifying the location using the
|
||||
common scp syntax (i.e. `user@host:/path/to/file`).
|
||||
|
||||
When lnav accesses a remote host, it transfers an agent (called the
|
||||
"tailer") to the host to handle file system requests from lnav. The agent
|
||||
is an [αcτµαlly pδrταblε εxεcµταblε](https://justine.lol/ape.html) that
|
||||
should run on most X86 Operating Systems. The agent will monitor the
|
||||
files of interest and synchronize their contents back to the host machine.
|
||||
In addition, the agent can be used to satisfy interactive requests for
|
||||
TAB-completion of remote file paths and previewing directory and file
|
||||
contents.
|
||||
|
||||
The following asciicast shows lnav opening log files on MacOS and FreeBSD:
|
||||
|
||||
<script id="asciicast-fblzf1Ir5Rr0b5wMGEJBb95ye"
|
||||
src="https://asciinema.org/a/fblzf1Ir5Rr0b5wMGEJBb95ye.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
layout: post
|
||||
title: Integration with regex101.com
|
||||
excerpt: Create/edit format files using regex101.com
|
||||
---
|
||||
|
||||
*(This change will be in the upcoming v0.11.0 release)*
|
||||
|
||||
Creating and updating format files for **lnav** can be a bit tedious and
|
||||
error-prone. To help streamline the process, an integration with regex101.com
|
||||
has been added. Now, you can create regular expressions for plaintext log
|
||||
files on https://regex101.com and then create a skeleton format file with a
|
||||
simple command. If you already have a format file that needs to be updated,
|
||||
you can push the regexes up to regex101, edit them with their interface, and
|
||||
then pull the changes back down as a format patch file.
|
||||
|
||||
To further improve the experience of developing with format files, there is
|
||||
also work underway to improve error messages. Many messages should be clearer,
|
||||
more context is provided, and they should look nicer as well. For example, the
|
||||
following error is displayed when a format regex is not valid:
|
||||
|
||||
![Screenshot of an error message](/assets/images/lnav-invalid-regex-error.png)
|
||||
|
||||
## Management CLI
|
||||
|
||||
The regex101 integration can be accessed through the new "management-mode CLI".
|
||||
This mode can be accessed by passing `-m` as the first option to **lnav**. The
|
||||
management CLI is organized as a series of nested commands. If you're not sure
|
||||
what to do at a given level, run the command as-is and the CLI should print out
|
||||
help text to guide you through the hierarchy of commands and required
|
||||
parameters.
|
||||
|
||||
### Create a format from a regular expression
|
||||
|
||||
The `regex101 import` command can be used to import a regular expression from
|
||||
regex101.com and create or patch a format file. The command takes the URL of
|
||||
the regex, the format name, and the name of the regex in the log format (
|
||||
defaults to "std" if not given). For example, the following command can be used
|
||||
to import the regex at "https://regex101.com/r/zpEnjV/2" into the format named "
|
||||
re101_example_log":
|
||||
|
||||
```console
|
||||
$ lnav -m regex101 import https://regex101.com/r/zpEnjV/2 re101_example_log
|
||||
```
|
||||
|
||||
If the import was successful, the path to the skeleton format file will be
|
||||
printed. You will most likely need to edit the file to fill in more details
|
||||
about your log format.
|
||||
|
||||
### Editing an existing regular expression
|
||||
|
||||
If you have a log format with a regex that needs to be updated, you can push
|
||||
the regex to regex101.com for editing with a command like (replace
|
||||
"myformat_log"/"std" with the name of your format and regex):
|
||||
|
||||
```console
|
||||
$ lnav -m format myformat_log regex std regex101 push
|
||||
```
|
||||
|
||||
Along with the regex, the format's samples will be added to the entry to ensure
|
||||
changes won't break existing matches. If the push was successful, the URL for
|
||||
the new regex101.com entry will be printed out. You can use that URL to edit the
|
||||
regex to your needs. Once you're done editing the regex, you can pull the
|
||||
changes down to a "patch" file using the following command:
|
||||
|
||||
```console
|
||||
$ lnav -m format myformat_log regex std regex101 pull
|
||||
```
|
||||
|
||||
The patch file will be evaluated after the original format file and override
|
||||
the values from the original. Once you are satisfied with the changes, you
|
||||
can move the contents of the patch file to the original file and delete the
|
||||
patch.
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
layout: post
|
||||
title: Pretty error messages
|
||||
excerpt: Error message improvements
|
||||
---
|
||||
|
||||
*(This change will be in the upcoming v0.11.0 release)*
|
||||
|
||||
Taking a page from compilers like rustc, I've spent some time
|
||||
improving error messages to make them look nicer and be more
|
||||
helpful. Fortunately, SQLite has improved their error reporting
|
||||
as well by adding
|
||||
[sqlite3_error_offset()](http://sqlite.com/c3ref/errcode.html).
|
||||
This function can point to the part of the SQL statement that
|
||||
was in error. As an example of the improvement, a SQL file
|
||||
that contained the following content:
|
||||
|
||||
```sql
|
||||
|
||||
-- This is a test
|
||||
SELECT abc),
|
||||
rtrim(def)
|
||||
FROM mytable;
|
||||
```
|
||||
|
||||
Would report an error like the following on startup in v0.10.1:
|
||||
|
||||
```text
|
||||
error:/Users/tstack/.config/lnav/formats/installed/test.sql:2:near ")": syntax error
|
||||
```
|
||||
|
||||
Now, you will get a clearer error message with a syntax-highlighted
|
||||
code snippet and a pointer to the part of the code that has the
|
||||
problem:
|
||||
|
||||
![Screenshot of a SQL error](/assets/images/lnav-sql-error-msg.png)
|
||||
|
||||
Inside the TUI, a panel has been added at the bottom to display these
|
||||
long-form error messages. The panel will disappear after a short
|
||||
time or when input is received. Here is an example showing an error
|
||||
for an invalid regular expression:
|
||||
|
||||
<script id="asciicast-lmYMLZsB02WbSO8VEz4aVLXa1"
|
||||
src="https://asciinema.org/a/lmYMLZsB02WbSO8VEz4aVLXa1.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
layout: post
|
||||
title: Markdown Support
|
||||
excerpt: A side effect of fancier help text
|
||||
---
|
||||
|
||||
*(This change will be in the upcoming v0.11.0 release)*
|
||||
|
||||
As part of the effort to polish the lnav TUI, I wanted to make the builtin
|
||||
help text look a bit nicer. The current help text is a plain text file with
|
||||
some ANSI escape sequences for colors. It's not easy to write or read. Since
|
||||
Markdown has become a dominant way to write this type of document, I figured
|
||||
I could use that and have the side benefit of allowing lnav to read Markdown
|
||||
docs. Fortunately, the [MD4C](https://github.com/mity/md4c) library exists.
|
||||
This library provides a nice event-driven parser for documents instead of
|
||||
just converting directly to HTML. In addition, document structure is now
|
||||
shown/navigable through the new breadcrumb bar at the top. I think the
|
||||
result is pretty nice:
|
||||
|
||||
<script id="asciicast-2hx3UiyzOHQXBQOBf31ztKvHc"
|
||||
src="https://asciinema.org/a/2hx3UiyzOHQXBQOBf31ztKvHc.js"
|
||||
async>
|
||||
</script>
|
||||
|
||||
## Viewing Markdown Files
|
||||
|
||||
Files with an `.md` suffix will be considered as Markdown and will be
|
||||
parsed as such. As an example, here is lnav displaying its README.md file:
|
||||
|
||||
<script id="asciicast-iw4rwddZNGCe3v8DyOfItERG9"
|
||||
src="https://asciinema.org/a/iw4rwddZNGCe3v8DyOfItERG9.js"
|
||||
async>
|
||||
</script>
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
layout: post
|
||||
title: Playground and Tutorial
|
||||
excerpt: Try lnav without having to install anything
|
||||
---
|
||||
|
||||
To make it easier to try out **lnav**, I've deployed an ssh-based playground
|
||||
and tutorial. You can SSH as follows to try them out:
|
||||
|
||||
```console
|
||||
$ ssh playground@demo.lnav.org
|
||||
$ ssh tutorial1@demo.lnav.org
|
||||
```
|
||||
|
||||
<script id="asciicast-HiiUMMmRKZh0uCVKm1Uw8WLlw"
|
||||
src="https://asciinema.org/a/HiiUMMmRKZh0uCVKm1Uw8WLlw.js"
|
||||
async>
|
||||
</script>
|
||||
|
||||
The playground has a couple of example logs to play with. The tutorial
|
||||
tries to guide you through the basics of navigating log files with lnav.
|
||||
The server is running on the free-tier of [fly.io](https://fly.io), so
|
||||
please be kind.
|
||||
|
||||
This effort was inspired by the `git.charm.sh` SSH server and by the
|
||||
[fasterthanli.me](https://fasterthanli.me/articles/remote-development-with-rust-on-fly-io)
|
||||
post on doing remote development on fly.io.
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
layout: post
|
||||
title: VSCode Extension for lnav
|
||||
excerpt: Syntax highlighting for lnav scripts
|
||||
---
|
||||
|
||||
I've published a simple [Visual Studio Code extension for lnav](
|
||||
https://marketplace.visualstudio.com/items?itemName=lnav.lnav)
|
||||
that adds syntax highlighting for scripts. The following is a
|
||||
screenshot showing the `dhclient-summary.lnav` script that is
|
||||
builtin:
|
||||
|
||||
![Screenshot of an lnav script](/assets/images/lnav-vscode-extension.png)
|
||||
|
||||
The lnav commands, those prefixed with colons, are marked as
|
||||
keywords and the SQL blocks are treated as an embedded language
|
||||
and highlighted accordingly.
|
||||
|
||||
If people find this useful, we can take it further and add
|
||||
support for running the current script/snippet in a new lnav
|
||||
process or even talking to an existing one.
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="1000" height="1000"><g transform="matrix(38.46153846153846,0,0,38.46153846153846,0,0)"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="26" height="26"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26">
|
||||
<path d="M 13 0.1875 C 5.925781 0.1875 0.1875 5.925781 0.1875 13 C 0.1875 20.074219 5.925781 25.8125 13 25.8125 C 20.074219 25.8125 25.8125 20.074219 25.8125 13 C 25.8125 5.925781 20.074219 0.1875 13 0.1875 Z M 11.9375 3.25 C 11.785156 3.464844 11.6875 3.71875 11.6875 4 C 11.6875 4.734375 12.265625 5.3125 13 5.3125 C 13.734375 5.3125 14.3125 4.734375 14.3125 4 C 14.3125 3.71875 14.214844 3.464844 14.0625 3.25 C 18.625 3.746094 22.253906 7.375 22.75 11.9375 C 22.535156 11.785156 22.28125 11.6875 22 11.6875 C 21.265625 11.6875 20.6875 12.265625 20.6875 13 C 20.6875 13.734375 21.265625 14.3125 22 14.3125 C 22.28125 14.3125 22.535156 14.214844 22.75 14.0625 C 22.253906 18.625 18.625 22.253906 14.0625 22.75 C 14.214844 22.535156 14.3125 22.28125 14.3125 22 C 14.3125 21.265625 13.734375 20.6875 13 20.6875 C 12.265625 20.6875 11.6875 21.265625 11.6875 22 C 11.6875 22.28125 11.785156 22.535156 11.9375 22.75 C 7.375 22.253906 3.746094 18.625 3.25 14.0625 C 3.464844 14.214844 3.71875 14.3125 4 14.3125 C 4.734375 14.3125 5.3125 13.734375 5.3125 13 C 5.3125 12.265625 4.734375 11.6875 4 11.6875 C 3.71875 11.6875 3.464844 11.785156 3.25 11.9375 C 3.746094 7.375 7.375 3.746094 11.9375 3.25 Z M 18.3125 7.6875 L 11.375 11.375 L 7.6875 18.3125 L 14.625 14.625 Z M 13 11.75 C 13.695313 11.75 14.25 12.304688 14.25 13 C 14.25 13.695313 13.695313 14.25 13 14.25 C 12.304688 14.25 11.75 13.695313 11.75 13 C 11.75 12.304688 12.304688 11.75 13 11.75 Z"></path>
|
||||
</svg></svg></g></svg>
|
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 373 KiB |
After Width: | Height: | Size: 158 KiB |
After Width: | Height: | Size: 183 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 306 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 26 KiB |