mirror of https://github.com/status-im/timbre.git
Merge branch 'dev'
This commit is contained in:
commit
b66c010cf4
|
@ -5,9 +5,8 @@
|
|||
/logs
|
||||
/docs
|
||||
/doc
|
||||
pom.xml
|
||||
*.jar
|
||||
*.class
|
||||
*.sh
|
||||
.lein*
|
||||
pom.xml*
|
||||
.env
|
||||
|
|
52
CHANGELOG.md
52
CHANGELOG.md
|
@ -1,14 +1,27 @@
|
|||
## Pending major release
|
||||
* Make Carmine appender resistant to unexpected log entry thaw errors.
|
||||
## v3.1.0 / 2014 Feb 23
|
||||
|
||||
### New
|
||||
|
||||
* #47 Added `taoensso.timbre.profiling/pspy*` fn.
|
||||
|
||||
### Changes
|
||||
|
||||
* Made Carmine appender resistant to unexpected log entry thaw errors.
|
||||
* Moved most utils to external `encore` dependency.
|
||||
|
||||
### Fixes
|
||||
|
||||
* #50 Fixed rotor appender so that it respects :fmt-output-opts (kenrestivo).
|
||||
|
||||
|
||||
## v3.0.0 / 2014-Jan-30
|
||||
## v3.0.0 / 2014 Jan 30
|
||||
|
||||
Major update, non-breaking though users with custom appenders are encouraged to view the _Changes_ section below. This version polishes up the codebase and general design. Tightened up a few aspects of how appenders and appender middleware work. Added a serializing Carmine appender (I use something similar in prod most of the time). Also finally added facilities for ad hoc (non-atom) logging configuration.
|
||||
> Major update, non-breaking though users with custom appenders are encouraged to view the _Changes_ section below. This version polishes up the codebase and general design. Tightened up a few aspects of how appenders and appender middleware work. Added a serializing Carmine appender (I use something similar in prod most of the time). Also finally added facilities for ad hoc (non-atom) logging configuration.
|
||||
>
|
||||
> Overall quite happy with the state of Timbre as of this release. No major anticipated improvements/changes from here (modulo bugs).
|
||||
|
||||
Overall quite happy with the state of Timbre as of this release. No major anticipated improvements/changes from here (modulo bugs).
|
||||
### New
|
||||
|
||||
### Features
|
||||
* Android appender, courtesy of AdamClements.
|
||||
* Rolling appender, courtesy of megayu.
|
||||
* Powerful, high-performance Carmine (Redis) appender: query-able, rotating serialized log entries by log level. See README or appender's docstring for details. (Recommended!)
|
||||
|
@ -19,20 +32,22 @@ Overall quite happy with the state of Timbre as of this release. No major antici
|
|||
* Appenders can now specify an optional `:fmt-output-opts` that'll get passed to `fmt-output-fn` for any special formatting requirements they may have (e.g. the Postal email appender provides an arg to suppress ANSI colors in stacktrace output).
|
||||
|
||||
### Changes
|
||||
* EXPERIMENTAL: stacktraces now formatted with `io.aviso/pretty` rather than clj-stacktrace. Feedback on this (esp. coloring) welcome!
|
||||
* DEPRECATED: `red`, `green`, `blue` -> use `color-str` instead.
|
||||
* DEPRECATED: config `prefix-fn` has been replaced by the more flexible `fmt-output-fn`. Change is backwards compatible.
|
||||
* REMOVED: Per-appender `:prefix` option dropped - was unnecessary. If an appender wants custom output formatting, it can do so w/o using an in-config formatter.
|
||||
|
||||
* **EXPERIMENTAL**: stacktraces now formatted with `io.aviso/pretty` rather than clj-stacktrace. Feedback on this (esp. coloring) welcome!
|
||||
* **DEPRECATED**: `red`, `green`, `blue` -> use `color-str` instead.
|
||||
* **DEPRECATED**: config `prefix-fn` has been replaced by the more flexible `fmt-output-fn`. Change is backwards compatible.
|
||||
* **REMOVED**: Per-appender `:prefix` option dropped - was unnecessary. If an appender wants custom output formatting, it can do so w/o using an in-config formatter.
|
||||
* Update `refer-timbre` (add profiling, logf variations, etc.).
|
||||
* DEPRECATED: atom logging level is now located in `level-atom` rather than `config`. Old in-config levels will be respected (i.e. change is backwards compatible).
|
||||
* DEPRECATED: appender rate limits are now specified as `:rate-limit [ncalls window-msecs]` rather than `:limit-per-msecs ncalls`. Change is backwards compatible.
|
||||
* **DEPRECATED**: atom logging level is now located in `level-atom` rather than `config`. Old in-config levels will be respected (i.e. change is backwards compatible).
|
||||
* **DEPRECATED**: appender rate limits are now specified as `:rate-limit [ncalls window-msecs]` rather than `:limit-per-msecs ncalls`. Change is backwards compatible.
|
||||
* Built-in appenders have been simplified using the new `default-output` appender arg.
|
||||
* Postal appender now generates a more useful subject in most cases.
|
||||
|
||||
### Fixes
|
||||
* [#38] Broken namespace filter (mlb-).
|
||||
* [unreported] Messages are now generated _after_ middleware has been applied, allowing better filtering performance and more intuitive behaviour (e.g. changes to args in middleware will now automatically percolate to message content).
|
||||
* [unreported] (logf <level> "hello %s") was throwing due to lack of formatting args.
|
||||
|
||||
* #38 Broken namespace filter (mlb-).
|
||||
* Messages are now generated _after_ middleware has been applied, allowing better filtering performance and more intuitive behaviour (e.g. changes to args in middleware will now automatically percolate to message content).
|
||||
* `(logf <level> "hello %s")` was throwing due to lack of formatting args.
|
||||
|
||||
|
||||
## v2.6.3 → v2.7.1
|
||||
|
@ -81,10 +96,3 @@ Overall quite happy with the state of Timbre as of this release. No major antici
|
|||
* **BREAKING**: `:more` appender arg has been dropped. `:message` arg is now a string of all arguments as joined by `logp`/`logf`. Appenders that need unjoined logging arguments (i.e. raw arguments as given to `logp`/`logf`) should use the new `:log-args` vector.
|
||||
|
||||
* **BREAKING**: Stacktraces are no longer automatically generated at the `log`-macro level. Stacktraces are now left as an appender implementation detail. A `:throwable` appender argument has been added along with a `stacktrace` fn.
|
||||
|
||||
|
||||
### For older versions please see the [commit history][]
|
||||
|
||||
[commit history]: https://github.com/ptaoussanis/timbre/commits/master
|
||||
[API docs]: http://ptaoussanis.github.io/timbre
|
||||
[Taoensso libs]: https://www.taoensso.com/clojure-libraries
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
Eclipse Public License - v 1.0
|
||||
|
||||
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
|
||||
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
|
||||
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||
|
||||
1. DEFINITIONS
|
||||
|
||||
"Contribution" means:
|
||||
|
||||
a) in the case of the initial Contributor, the initial code and documentation
|
||||
distributed under this Agreement, and
|
||||
b) in the case of each subsequent Contributor:
|
||||
i) changes to the Program, and
|
||||
ii) additions to the Program;
|
||||
|
||||
where such changes and/or additions to the Program originate from and are
|
||||
distributed by that particular Contributor. A Contribution 'originates' from
|
||||
a Contributor if it was added to the Program by such Contributor itself or
|
||||
anyone acting on such Contributor's behalf. Contributions do not include
|
||||
additions to the Program which: (i) are separate modules of software
|
||||
distributed in conjunction with the Program under their own license
|
||||
agreement, and (ii) are not derivative works of the Program.
|
||||
|
||||
"Contributor" means any person or entity that distributes the Program.
|
||||
|
||||
"Licensed Patents" mean patent claims licensable by a Contributor which are
|
||||
necessarily infringed by the use or sale of its Contribution alone or when
|
||||
combined with the Program.
|
||||
|
||||
"Program" means the Contributions distributed in accordance with this Agreement.
|
||||
|
||||
"Recipient" means anyone who receives the Program under this Agreement,
|
||||
including all Contributors.
|
||||
|
||||
2. GRANT OF RIGHTS
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free copyright license to
|
||||
reproduce, prepare derivative works of, publicly display, publicly perform,
|
||||
distribute and sublicense the Contribution of such Contributor, if any, and
|
||||
such derivative works, in source code and object code form.
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free patent license under
|
||||
Licensed Patents to make, use, sell, offer to sell, import and otherwise
|
||||
transfer the Contribution of such Contributor, if any, in source code and
|
||||
object code form. This patent license shall apply to the combination of the
|
||||
Contribution and the Program if, at the time the Contribution is added by
|
||||
the Contributor, such addition of the Contribution causes such combination
|
||||
to be covered by the Licensed Patents. The patent license shall not apply
|
||||
to any other combinations which include the Contribution. No hardware per
|
||||
se is licensed hereunder.
|
||||
c) Recipient understands that although each Contributor grants the licenses to
|
||||
its Contributions set forth herein, no assurances are provided by any
|
||||
Contributor that the Program does not infringe the patent or other
|
||||
intellectual property rights of any other entity. Each Contributor
|
||||
disclaims any liability to Recipient for claims brought by any other entity
|
||||
based on infringement of intellectual property rights or otherwise. As a
|
||||
condition to exercising the rights and licenses granted hereunder, each
|
||||
Recipient hereby assumes sole responsibility to secure any other
|
||||
intellectual property rights needed, if any. For example, if a third party
|
||||
patent license is required to allow Recipient to distribute the Program, it
|
||||
is Recipient's responsibility to acquire that license before distributing
|
||||
the Program.
|
||||
d) Each Contributor represents that to its knowledge it has sufficient
|
||||
copyright rights in its Contribution, if any, to grant the copyright
|
||||
license set forth in this Agreement.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
A Contributor may choose to distribute the Program in object code form under its
|
||||
own license agreement, provided that:
|
||||
|
||||
a) it complies with the terms and conditions of this Agreement; and
|
||||
b) its license agreement:
|
||||
i) effectively disclaims on behalf of all Contributors all warranties and
|
||||
conditions, express and implied, including warranties or conditions of
|
||||
title and non-infringement, and implied warranties or conditions of
|
||||
merchantability and fitness for a particular purpose;
|
||||
ii) effectively excludes on behalf of all Contributors all liability for
|
||||
damages, including direct, indirect, special, incidental and
|
||||
consequential damages, such as lost profits;
|
||||
iii) states that any provisions which differ from this Agreement are offered
|
||||
by that Contributor alone and not by any other party; and
|
||||
iv) states that source code for the Program is available from such
|
||||
Contributor, and informs licensees how to obtain it in a reasonable
|
||||
manner on or through a medium customarily used for software exchange.
|
||||
|
||||
When the Program is made available in source code form:
|
||||
|
||||
a) it must be made available under this Agreement; and
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
Contributors may not remove or alter any copyright notices contained within
|
||||
the Program.
|
||||
|
||||
Each Contributor must identify itself as the originator of its Contribution, if
|
||||
any, in a manner that reasonably allows subsequent Recipients to identify the
|
||||
originator of the Contribution.
|
||||
|
||||
4. COMMERCIAL DISTRIBUTION
|
||||
|
||||
Commercial distributors of software may accept certain responsibilities with
|
||||
respect to end users, business partners and the like. While this license is
|
||||
intended to facilitate the commercial use of the Program, the Contributor who
|
||||
includes the Program in a commercial product offering should do so in a manner
|
||||
which does not create potential liability for other Contributors. Therefore, if
|
||||
a Contributor includes the Program in a commercial product offering, such
|
||||
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
|
||||
every other Contributor ("Indemnified Contributor") against any losses, damages
|
||||
and costs (collectively "Losses") arising from claims, lawsuits and other legal
|
||||
actions brought by a third party against the Indemnified Contributor to the
|
||||
extent caused by the acts or omissions of such Commercial Contributor in
|
||||
connection with its distribution of the Program in a commercial product
|
||||
offering. The obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In order
|
||||
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
|
||||
Contributor in writing of such claim, and b) allow the Commercial Contributor to
|
||||
control, and cooperate with the Commercial Contributor in, the defense and any
|
||||
related settlement negotiations. The Indemnified Contributor may participate in
|
||||
any such claim at its own expense.
|
||||
|
||||
For example, a Contributor might include the Program in a commercial product
|
||||
offering, Product X. That Contributor is then a Commercial Contributor. If that
|
||||
Commercial Contributor then makes performance claims, or offers warranties
|
||||
related to Product X, those performance claims and warranties are such
|
||||
Commercial Contributor's responsibility alone. Under this section, the
|
||||
Commercial Contributor would have to defend claims against the other
|
||||
Contributors related to those performance claims and warranties, and if a court
|
||||
requires any other Contributor to pay any damages as a result, the Commercial
|
||||
Contributor must pay those damages.
|
||||
|
||||
5. NO WARRANTY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
|
||||
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
|
||||
Recipient is solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its exercise of
|
||||
rights under this Agreement , including but not limited to the risks and costs
|
||||
of program errors, compliance with applicable laws, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
6. DISCLAIMER OF LIABILITY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
|
||||
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
|
||||
PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
|
||||
GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. GENERAL
|
||||
|
||||
If any provision of this Agreement is invalid or unenforceable under applicable
|
||||
law, it shall not affect the validity or enforceability of the remainder of the
|
||||
terms of this Agreement, and without further action by the parties hereto, such
|
||||
provision shall be reformed to the minimum extent necessary to make such
|
||||
provision valid and enforceable.
|
||||
|
||||
If Recipient institutes patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
|
||||
(excluding combinations of the Program with other software or hardware)
|
||||
infringes such Recipient's patent(s), then such Recipient's rights granted under
|
||||
Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient's rights under this Agreement shall terminate if it fails to
|
||||
comply with any of the material terms or conditions of this Agreement and does
|
||||
not cure such failure in a reasonable period of time after becoming aware of
|
||||
such noncompliance. If all Recipient's rights under this Agreement terminate,
|
||||
Recipient agrees to cease use and distribution of the Program as soon as
|
||||
reasonably practicable. However, Recipient's obligations under this Agreement
|
||||
and any licenses granted by Recipient relating to the Program shall continue and
|
||||
survive.
|
||||
|
||||
Everyone is permitted to copy and distribute copies of this Agreement, but in
|
||||
order to avoid inconsistency the Agreement is copyrighted and may only be
|
||||
modified in the following manner. The Agreement Steward reserves the right to
|
||||
publish new versions (including revisions) of this Agreement from time to time.
|
||||
No one other than the Agreement Steward has the right to modify this Agreement.
|
||||
The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation
|
||||
may assign the responsibility to serve as the Agreement Steward to a suitable
|
||||
separate entity. Each new version of the Agreement will be given a
|
||||
distinguishing version number. The Program (including Contributions) may always
|
||||
be distributed subject to the version of the Agreement under which it was
|
||||
received. In addition, after a new version of the Agreement is published,
|
||||
Contributor may elect to distribute the Program (including its Contributions)
|
||||
under the new version. Except as expressly stated in Sections 2(a) and 2(b)
|
||||
above, Recipient receives no rights or licenses to the intellectual property of
|
||||
any Contributor under this Agreement, whether expressly, by implication,
|
||||
estoppel or otherwise. All rights in the Program not expressly granted under
|
||||
this Agreement are reserved.
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the
|
||||
intellectual property laws of the United States of America. No party to this
|
||||
Agreement will bring a legal action under this Agreement more than one year
|
||||
after the cause of action arose. Each party waives its rights to a jury trial in
|
||||
any resulting litigation.
|
39
README.md
39
README.md
|
@ -1,7 +1,7 @@
|
|||
**[API docs](http://ptaoussanis.github.io/timbre/)** | **[CHANGELOG](https://github.com/ptaoussanis/timbre/blob/master/CHANGELOG.md)** | [contact & contributing](#contact--contribution) | [other Clojure libs](https://www.taoensso.com/clojure-libraries) | [Twitter](https://twitter.com/#!/ptaoussanis) | current [semantic](http://semver.org/) version:
|
||||
**[API docs][]** | **[CHANGELOG][]** | [other Clojure libs][] | [Twitter][] | [contact/contributing](#contact--contributing) | current ([semantic][]) version:
|
||||
|
||||
```clojure
|
||||
[com.taoensso/timbre "3.0.1"] ; Non-breaking upgrade - see CHANGELOG for details
|
||||
[com.taoensso/timbre "3.1.0"] ; 3.x is a non-breaking upgrade - see CHANGELOG for details
|
||||
```
|
||||
|
||||
Appender authors: please see [here](https://github.com/ptaoussanis/timbre/issues/41) about migrating Timbre 2.x appenders to 3.x's recommended style.
|
||||
|
@ -27,10 +27,10 @@ Logging with Java can be maddeningly, unnecessarily hard. Particularly if all yo
|
|||
|
||||
### Dependencies
|
||||
|
||||
Add the necessary dependency to your [Leiningen](http://leiningen.org/) `project.clj` and use the supplied ns-import helper:
|
||||
Add the necessary dependency to your [Leiningen][] `project.clj` and use the supplied ns-import helper:
|
||||
|
||||
```clojure
|
||||
[com.taoensso/timbre "3.0.1"] ; project.clj
|
||||
[com.taoensso/timbre "3.1.0"] ; project.clj
|
||||
|
||||
(ns my-app (:require [taoensso.timbre :as timbre])) ; Your ns
|
||||
(timbre/refer-timbre) ; Provides useful Timbre aliases in this ns
|
||||
|
@ -41,9 +41,8 @@ The `refer-timbre` call is a convenience fn that executes:
|
|||
(require '[taoensso.timbre :as timbre
|
||||
:refer (log trace debug info warn error fatal report
|
||||
logf tracef debugf infof warnf errorf fatalf reportf
|
||||
spy logged-future with-log-level)])
|
||||
(require '[taoensso.timbre.utils :refer (sometimes)])
|
||||
(require '[taoensso.timbre.profiling :as profiling :refer (pspy profile defnp)])
|
||||
spy logged-future with-log-level sometimes)])
|
||||
(require '[taoensso.timbre.profiling :as profiling :refer (pspy pspy* profile defnp)])
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
@ -268,16 +267,30 @@ A simple **sampling profiler** is also available: `taoensso.timbre.profiling/sam
|
|||
|
||||
## This project supports the CDS and ![ClojureWerkz](https://raw.github.com/clojurewerkz/clojurewerkz.org/master/assets/images/logos/clojurewerkz_long_h_50.png) goals
|
||||
|
||||
* [CDS](http://clojure-doc.org/), the **Clojure Documentation Site**, is a **contributer-friendly** community project aimed at producing top-notch, **beginner-friendly** Clojure tutorials and documentation. Awesome resource.
|
||||
* [CDS][], the **Clojure Documentation Site**, is a **contributer-friendly** community project aimed at producing top-notch, **beginner-friendly** Clojure tutorials and documentation. Awesome resource.
|
||||
|
||||
* [ClojureWerkz](http://clojurewerkz.org/) is a growing collection of open-source, **batteries-included Clojure libraries** that emphasise modern targets, great documentation, and thorough testing. They've got a ton of great stuff, check 'em out!
|
||||
* [ClojureWerkz][] is a growing collection of open-source, **batteries-included Clojure libraries** that emphasise modern targets, great documentation, and thorough testing. They've got a ton of great stuff, check 'em out!
|
||||
|
||||
## Contact & contribution
|
||||
## Contact & contributing
|
||||
|
||||
Please use the [project's GitHub issues page](https://github.com/ptaoussanis/timbre/issues) for project questions/comments/suggestions/whatever **(pull requests welcome!)**. Am very open to ideas if you have any!
|
||||
Please use the project's GitHub [issues page][] for project questions/comments/suggestions/whatever **(pull requests welcome!)**. Am very open to ideas if you have any!
|
||||
|
||||
Otherwise reach me (Peter Taoussanis) at [taoensso.com](https://www.taoensso.com) or on Twitter ([@ptaoussanis](https://twitter.com/#!/ptaoussanis)). Cheers!
|
||||
Otherwise reach me (Peter Taoussanis) at [taoensso.com][] or on [Twitter][]. Cheers!
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2012, 2013 Peter Taoussanis. Distributed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html), the same as Clojure.
|
||||
Copyright © 2012-2014 Peter Taoussanis. Distributed under the [Eclipse Public License][], the same as Clojure.
|
||||
|
||||
|
||||
[API docs]: <http://ptaoussanis.github.io/timbre/>
|
||||
[CHANGELOG]: <https://github.com/ptaoussanis/nippy/blob/master/CHANGELOG.md>
|
||||
[other Clojure libs]: <https://www.taoensso.com/clojure-libraries>
|
||||
[Twitter]: <https://twitter.com/ptaoussanis>
|
||||
[semantic]: <http://semver.org/>
|
||||
[Leiningen]: <http://leiningen.org/>
|
||||
[CDS]: <http://clojure-doc.org/>
|
||||
[ClojureWerkz]: <http://clojurewerkz.org/>
|
||||
[issues page]: <https://github.com/ptaoussanis/nippy/issues>
|
||||
[commit history]: <https://github.com/ptaoussanis/nippy/commits/master>
|
||||
[taoensso.com]: <https://www.taoensso.com>
|
||||
[Eclipse Public License]: <https://raw2.github.com/ptaoussanis/nippy/master/LICENSE>
|
||||
|
|
261
epl-v10.html
261
epl-v10.html
|
@ -1,261 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
|
||||
<title>Eclipse Public License - Version 1.0</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
size: 8.5in 11.0in;
|
||||
margin: 0.25in 0.5in 0.25in 0.5in;
|
||||
tab-interval: 0.5in;
|
||||
}
|
||||
p {
|
||||
margin-left: auto;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
p.list {
|
||||
margin-left: 0.5in;
|
||||
margin-top: 0.05em;
|
||||
margin-bottom: 0.05em;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body lang="EN-US">
|
||||
|
||||
<p align=center><b>Eclipse Public License - v 1.0</b></p>
|
||||
|
||||
<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
|
||||
PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
|
||||
DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
|
||||
AGREEMENT.</p>
|
||||
|
||||
<p><b>1. DEFINITIONS</b></p>
|
||||
|
||||
<p>"Contribution" means:</p>
|
||||
|
||||
<p class="list">a) in the case of the initial Contributor, the initial
|
||||
code and documentation distributed under this Agreement, and</p>
|
||||
<p class="list">b) in the case of each subsequent Contributor:</p>
|
||||
<p class="list">i) changes to the Program, and</p>
|
||||
<p class="list">ii) additions to the Program;</p>
|
||||
<p class="list">where such changes and/or additions to the Program
|
||||
originate from and are distributed by that particular Contributor. A
|
||||
Contribution 'originates' from a Contributor if it was added to the
|
||||
Program by such Contributor itself or anyone acting on such
|
||||
Contributor's behalf. Contributions do not include additions to the
|
||||
Program which: (i) are separate modules of software distributed in
|
||||
conjunction with the Program under their own license agreement, and (ii)
|
||||
are not derivative works of the Program.</p>
|
||||
|
||||
<p>"Contributor" means any person or entity that distributes
|
||||
the Program.</p>
|
||||
|
||||
<p>"Licensed Patents" mean patent claims licensable by a
|
||||
Contributor which are necessarily infringed by the use or sale of its
|
||||
Contribution alone or when combined with the Program.</p>
|
||||
|
||||
<p>"Program" means the Contributions distributed in accordance
|
||||
with this Agreement.</p>
|
||||
|
||||
<p>"Recipient" means anyone who receives the Program under
|
||||
this Agreement, including all Contributors.</p>
|
||||
|
||||
<p><b>2. GRANT OF RIGHTS</b></p>
|
||||
|
||||
<p class="list">a) Subject to the terms of this Agreement, each
|
||||
Contributor hereby grants Recipient a non-exclusive, worldwide,
|
||||
royalty-free copyright license to reproduce, prepare derivative works
|
||||
of, publicly display, publicly perform, distribute and sublicense the
|
||||
Contribution of such Contributor, if any, and such derivative works, in
|
||||
source code and object code form.</p>
|
||||
|
||||
<p class="list">b) Subject to the terms of this Agreement, each
|
||||
Contributor hereby grants Recipient a non-exclusive, worldwide,
|
||||
royalty-free patent license under Licensed Patents to make, use, sell,
|
||||
offer to sell, import and otherwise transfer the Contribution of such
|
||||
Contributor, if any, in source code and object code form. This patent
|
||||
license shall apply to the combination of the Contribution and the
|
||||
Program if, at the time the Contribution is added by the Contributor,
|
||||
such addition of the Contribution causes such combination to be covered
|
||||
by the Licensed Patents. The patent license shall not apply to any other
|
||||
combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder.</p>
|
||||
|
||||
<p class="list">c) Recipient understands that although each Contributor
|
||||
grants the licenses to its Contributions set forth herein, no assurances
|
||||
are provided by any Contributor that the Program does not infringe the
|
||||
patent or other intellectual property rights of any other entity. Each
|
||||
Contributor disclaims any liability to Recipient for claims brought by
|
||||
any other entity based on infringement of intellectual property rights
|
||||
or otherwise. As a condition to exercising the rights and licenses
|
||||
granted hereunder, each Recipient hereby assumes sole responsibility to
|
||||
secure any other intellectual property rights needed, if any. For
|
||||
example, if a third party patent license is required to allow Recipient
|
||||
to distribute the Program, it is Recipient's responsibility to acquire
|
||||
that license before distributing the Program.</p>
|
||||
|
||||
<p class="list">d) Each Contributor represents that to its knowledge it
|
||||
has sufficient copyright rights in its Contribution, if any, to grant
|
||||
the copyright license set forth in this Agreement.</p>
|
||||
|
||||
<p><b>3. REQUIREMENTS</b></p>
|
||||
|
||||
<p>A Contributor may choose to distribute the Program in object code
|
||||
form under its own license agreement, provided that:</p>
|
||||
|
||||
<p class="list">a) it complies with the terms and conditions of this
|
||||
Agreement; and</p>
|
||||
|
||||
<p class="list">b) its license agreement:</p>
|
||||
|
||||
<p class="list">i) effectively disclaims on behalf of all Contributors
|
||||
all warranties and conditions, express and implied, including warranties
|
||||
or conditions of title and non-infringement, and implied warranties or
|
||||
conditions of merchantability and fitness for a particular purpose;</p>
|
||||
|
||||
<p class="list">ii) effectively excludes on behalf of all Contributors
|
||||
all liability for damages, including direct, indirect, special,
|
||||
incidental and consequential damages, such as lost profits;</p>
|
||||
|
||||
<p class="list">iii) states that any provisions which differ from this
|
||||
Agreement are offered by that Contributor alone and not by any other
|
||||
party; and</p>
|
||||
|
||||
<p class="list">iv) states that source code for the Program is available
|
||||
from such Contributor, and informs licensees how to obtain it in a
|
||||
reasonable manner on or through a medium customarily used for software
|
||||
exchange.</p>
|
||||
|
||||
<p>When the Program is made available in source code form:</p>
|
||||
|
||||
<p class="list">a) it must be made available under this Agreement; and</p>
|
||||
|
||||
<p class="list">b) a copy of this Agreement must be included with each
|
||||
copy of the Program.</p>
|
||||
|
||||
<p>Contributors may not remove or alter any copyright notices contained
|
||||
within the Program.</p>
|
||||
|
||||
<p>Each Contributor must identify itself as the originator of its
|
||||
Contribution, if any, in a manner that reasonably allows subsequent
|
||||
Recipients to identify the originator of the Contribution.</p>
|
||||
|
||||
<p><b>4. COMMERCIAL DISTRIBUTION</b></p>
|
||||
|
||||
<p>Commercial distributors of software may accept certain
|
||||
responsibilities with respect to end users, business partners and the
|
||||
like. While this license is intended to facilitate the commercial use of
|
||||
the Program, the Contributor who includes the Program in a commercial
|
||||
product offering should do so in a manner which does not create
|
||||
potential liability for other Contributors. Therefore, if a Contributor
|
||||
includes the Program in a commercial product offering, such Contributor
|
||||
("Commercial Contributor") hereby agrees to defend and
|
||||
indemnify every other Contributor ("Indemnified Contributor")
|
||||
against any losses, damages and costs (collectively "Losses")
|
||||
arising from claims, lawsuits and other legal actions brought by a third
|
||||
party against the Indemnified Contributor to the extent caused by the
|
||||
acts or omissions of such Commercial Contributor in connection with its
|
||||
distribution of the Program in a commercial product offering. The
|
||||
obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In
|
||||
order to qualify, an Indemnified Contributor must: a) promptly notify
|
||||
the Commercial Contributor in writing of such claim, and b) allow the
|
||||
Commercial Contributor to control, and cooperate with the Commercial
|
||||
Contributor in, the defense and any related settlement negotiations. The
|
||||
Indemnified Contributor may participate in any such claim at its own
|
||||
expense.</p>
|
||||
|
||||
<p>For example, a Contributor might include the Program in a commercial
|
||||
product offering, Product X. That Contributor is then a Commercial
|
||||
Contributor. If that Commercial Contributor then makes performance
|
||||
claims, or offers warranties related to Product X, those performance
|
||||
claims and warranties are such Commercial Contributor's responsibility
|
||||
alone. Under this section, the Commercial Contributor would have to
|
||||
defend claims against the other Contributors related to those
|
||||
performance claims and warranties, and if a court requires any other
|
||||
Contributor to pay any damages as a result, the Commercial Contributor
|
||||
must pay those damages.</p>
|
||||
|
||||
<p><b>5. NO WARRANTY</b></p>
|
||||
|
||||
<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
|
||||
PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
|
||||
ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
|
||||
OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement , including but not limited to
|
||||
the risks and costs of program errors, compliance with applicable laws,
|
||||
damage to or loss of data, programs or equipment, and unavailability or
|
||||
interruption of operations.</p>
|
||||
|
||||
<p><b>6. DISCLAIMER OF LIABILITY</b></p>
|
||||
|
||||
<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
|
||||
NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
|
||||
WITHOUT LIMITATION LOST PROFITS), 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 OR
|
||||
DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
|
||||
|
||||
<p><b>7. GENERAL</b></p>
|
||||
|
||||
<p>If any provision of this Agreement is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of
|
||||
the remainder of the terms of this Agreement, and without further action
|
||||
by the parties hereto, such provision shall be reformed to the minimum
|
||||
extent necessary to make such provision valid and enforceable.</p>
|
||||
|
||||
<p>If Recipient institutes patent litigation against any entity
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that the
|
||||
Program itself (excluding combinations of the Program with other
|
||||
software or hardware) infringes such Recipient's patent(s), then such
|
||||
Recipient's rights granted under Section 2(b) shall terminate as of the
|
||||
date such litigation is filed.</p>
|
||||
|
||||
<p>All Recipient's rights under this Agreement shall terminate if it
|
||||
fails to comply with any of the material terms or conditions of this
|
||||
Agreement and does not cure such failure in a reasonable period of time
|
||||
after becoming aware of such noncompliance. If all Recipient's rights
|
||||
under this Agreement terminate, Recipient agrees to cease use and
|
||||
distribution of the Program as soon as reasonably practicable. However,
|
||||
Recipient's obligations under this Agreement and any licenses granted by
|
||||
Recipient relating to the Program shall continue and survive.</p>
|
||||
|
||||
<p>Everyone is permitted to copy and distribute copies of this
|
||||
Agreement, but in order to avoid inconsistency the Agreement is
|
||||
copyrighted and may only be modified in the following manner. The
|
||||
Agreement Steward reserves the right to publish new versions (including
|
||||
revisions) of this Agreement from time to time. No one other than the
|
||||
Agreement Steward has the right to modify this Agreement. The Eclipse
|
||||
Foundation is the initial Agreement Steward. The Eclipse Foundation may
|
||||
assign the responsibility to serve as the Agreement Steward to a
|
||||
suitable separate entity. Each new version of the Agreement will be
|
||||
given a distinguishing version number. The Program (including
|
||||
Contributions) may always be distributed subject to the version of the
|
||||
Agreement under which it was received. In addition, after a new version
|
||||
of the Agreement is published, Contributor may elect to distribute the
|
||||
Program (including its Contributions) under the new version. Except as
|
||||
expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
|
||||
rights or licenses to the intellectual property of any Contributor under
|
||||
this Agreement, whether expressly, by implication, estoppel or
|
||||
otherwise. All rights in the Program not expressly granted under this
|
||||
Agreement are reserved.</p>
|
||||
|
||||
<p>This Agreement is governed by the laws of the State of New York and
|
||||
the intellectual property laws of the United States of America. No party
|
||||
to this Agreement will bring a legal action under this Agreement more
|
||||
than one year after the cause of action arose. Each party waives its
|
||||
rights to a jury trial in any resulting litigation.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
68
project.clj
68
project.clj
|
@ -1,29 +1,51 @@
|
|||
(defproject com.taoensso/timbre "3.0.1"
|
||||
(defproject com.taoensso/timbre "3.1.0"
|
||||
:author "Peter Taoussanis <https://www.taoensso.com>"
|
||||
:description "Clojure logging & profiling library"
|
||||
:url "https://github.com/ptaoussanis/timbre"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.4.0"]
|
||||
[org.clojure/tools.macro "0.1.5"]
|
||||
[io.aviso/pretty "0.1.8"]]
|
||||
:profiles {:1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]}
|
||||
:1.5 {:dependencies [[org.clojure/clojure "1.5.1"]]}
|
||||
:1.6 {:dependencies [[org.clojure/clojure "1.6.0-alpha2"]]}
|
||||
:dev {:dependencies [[com.draines/postal "1.11.1"]
|
||||
[com.taoensso/carmine "2.4.0"]
|
||||
[com.taoensso/nippy "2.5.2"] ; nb .1+
|
||||
[org.clojure/tools.logging "0.2.6"]]}
|
||||
:test {:dependencies [[expectations "1.4.56"]]}}
|
||||
:aliases {"test-all" ["with-profile" "+test,+1.4:+test,+1.5:+test,+1.6" "expectations"]
|
||||
"test-auto" ["with-profile" "+test" "autoexpect"]
|
||||
"start-dev" ["with-profile" "+dev,+test,+bench" "repl" ":headless"]
|
||||
"codox" ["with-profile" "+dev,+test" "doc"]}
|
||||
:plugins [[lein-expectations "0.0.8"]
|
||||
[lein-autoexpect "1.2.1"]
|
||||
[lein-ancient "0.5.4"]
|
||||
[codox "0.6.6"]]
|
||||
:min-lein-version "2.0.0"
|
||||
:global-vars {*warn-on-reflection* true}
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"
|
||||
:distribution :repo
|
||||
:comments "Same as Clojure"}
|
||||
:min-lein-version "2.3.3"
|
||||
:global-vars {*warn-on-reflection* true
|
||||
*assert* true}
|
||||
:dependencies
|
||||
[[org.clojure/clojure "1.4.0"]
|
||||
[io.aviso/pretty "0.1.8"]
|
||||
[com.taoensso/encore "0.8.0"]]
|
||||
|
||||
:test-paths ["test" "src"]
|
||||
:profiles
|
||||
{:build {:hooks ^:replace []} ; Workaround to avoid :dev hooks during deploy
|
||||
:1.5 {:dependencies [[org.clojure/clojure "1.5.1"]]}
|
||||
:1.6 {:dependencies [[org.clojure/clojure "1.6.0-beta1"]]}
|
||||
:test {:dependencies [[expectations "1.4.56"]
|
||||
[reiddraper/simple-check "0.5.6"]
|
||||
[org.xerial.snappy/snappy-java "1.1.1-M1"]
|
||||
[org.clojure/data.fressian "0.2.0"]]
|
||||
:plugins [[lein-expectations "0.0.8"]
|
||||
[lein-autoexpect "1.2.2"]]}
|
||||
:dev
|
||||
[:1.6 :test
|
||||
{:jvm-opts ^:replace ["-server"]
|
||||
:hooks []
|
||||
:dependencies [[com.draines/postal "1.11.1"]
|
||||
[org.clojure/tools.logging "0.2.6"]
|
||||
[com.taoensso/nippy "2.5.2"]
|
||||
[com.taoensso/carmine "2.4.6"]]
|
||||
:plugins []}]}
|
||||
|
||||
:plugins [[lein-ancient "0.5.4"]
|
||||
[codox "0.6.7"]]
|
||||
|
||||
;; :codox {:sources ["target/classes"]} ; For use with cljx
|
||||
:aliases
|
||||
{"test-all" ["with-profile" "+test:+1.5,+test:+1.6,+test" "expectations"]
|
||||
"test-auto" ["with-profile" "+test" "autoexpect"]
|
||||
"start-dev" ["with-profile" "+dev" "repl" ":headless"]
|
||||
"codox" ["with-profile" "+test" "doc"]
|
||||
"deploy-lib" ["with-profile" "+dev,+build" "do" "deploy" "clojars," "install"]}
|
||||
|
||||
:repositories
|
||||
{"sonatype"
|
||||
{:url "http://oss.sonatype.org/content/repositories/releases"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{:author "Peter Taoussanis"}
|
||||
(:require [clojure.string :as str]
|
||||
[io.aviso.exception :as aviso-ex]
|
||||
[taoensso.timbre.utils :as utils])
|
||||
[taoensso.encore :as encore])
|
||||
(:import [java.util Date Locale]
|
||||
[java.text SimpleDateFormat]))
|
||||
|
||||
|
@ -42,6 +42,12 @@
|
|||
|
||||
(comment (stacktrace (Exception. "foo") nil {}))
|
||||
|
||||
(defmacro sometimes
|
||||
"Executes body with probability e/o [0,1]. Useful for sampled logging."
|
||||
[probability & body]
|
||||
`(do (assert (<= 0 ~probability 1) "Probability: 0 <= p <= 1")
|
||||
(when (< (rand) ~probability) ~@body)))
|
||||
|
||||
;;;; Logging levels
|
||||
|
||||
(def level-compile-time
|
||||
|
@ -171,9 +177,9 @@
|
|||
(try (spit filename (str output "\n") :append true)
|
||||
(catch java.io.IOException _))))}}})
|
||||
|
||||
(utils/defonce* config (atom example-config))
|
||||
(encore/defonce* config (atom example-config))
|
||||
(defn set-config! [ks val] (swap! config assoc-in ks val))
|
||||
(defn merge-config! [& maps] (apply swap! config utils/merge-deep maps))
|
||||
(defn merge-config! [& maps] (apply swap! config encore/merge-deep maps))
|
||||
|
||||
;;;; Appender-fn decoration
|
||||
|
||||
|
@ -221,11 +227,11 @@
|
|||
;; Compile-time:
|
||||
(if-not rate-limit apfn
|
||||
(let [[ncalls-limit window-ms] rate-limit
|
||||
limiter-any (utils/rate-limiter ncalls-limit window-ms)
|
||||
limiter-any (encore/rate-limiter ncalls-limit window-ms)
|
||||
;; This is a little hand-wavy but it's a decent general
|
||||
;; strategy and helps us from making this overly complex to
|
||||
;; configure.
|
||||
limiter-specific (utils/rate-limiter (quot ncalls-limit 4)
|
||||
limiter-specific (encore/rate-limiter (quot ncalls-limit 4)
|
||||
window-ms)]
|
||||
(fn [{:keys [ns args] :as apfn-args}]
|
||||
;; Runtime: (test smaller limit 1st):
|
||||
|
@ -256,7 +262,7 @@
|
|||
(comment ((make-timestamp-fn "yyyy-MMM-dd" nil) (Date.)))
|
||||
|
||||
(def ^:private get-hostname
|
||||
(utils/memoize-ttl 60000
|
||||
(encore/memoize* 60000
|
||||
(fn []
|
||||
(let [p (promise)]
|
||||
(future ; Android doesn't like this on the main thread
|
||||
|
@ -499,19 +505,17 @@
|
|||
'[taoensso.timbre :as timbre
|
||||
:refer (log trace debug info warn error fatal report
|
||||
logf tracef debugf infof warnf errorf fatalf reportf
|
||||
spy logged-future with-log-level)])
|
||||
(require '[taoensso.timbre.utils :refer (sometimes)])
|
||||
spy logged-future with-log-level sometimes)])
|
||||
(require
|
||||
'[taoensso.timbre.profiling :as profiling :refer (pspy profile defnp)])"
|
||||
'[taoensso.timbre.profiling :as profiling :refer (pspy pspy* profile defnp)])"
|
||||
[]
|
||||
(require
|
||||
'[taoensso.timbre :as timbre
|
||||
:refer (log trace debug info warn error fatal report
|
||||
logf tracef debugf infof warnf errorf fatalf reportf
|
||||
spy logged-future with-log-level)])
|
||||
(require '[taoensso.timbre.utils :refer (sometimes)])
|
||||
spy logged-future with-log-level sometimes)])
|
||||
(require
|
||||
'[taoensso.timbre.profiling :as profiling :refer (pspy profile defnp)]))
|
||||
'[taoensso.timbre.profiling :as profiling :refer (pspy pspy* profile defnp)]))
|
||||
|
||||
;;;; Deprecated
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
also offer interesting opportunities here.
|
||||
|
||||
See accompanying `query-entries` fn to return deserialized log entries."
|
||||
[& [appender-opts {:keys [conn keyfn args-hash-fn nentries-by-level]
|
||||
[& [appender-opts {:keys [conn-opts keyfn args-hash-fn nentries-by-level]
|
||||
:or {keyfn default-keyfn
|
||||
args-hash-fn timbre/default-args-hash-fn
|
||||
nentries-by-level {:trace 50
|
||||
|
@ -40,7 +40,8 @@
|
|||
:warn 100
|
||||
:error 100
|
||||
:fatal 100
|
||||
:report 100}}}]]
|
||||
:report 100}}
|
||||
:as opts}]]
|
||||
{:pre [(string? (keyfn "test"))
|
||||
(every? #(contains? nentries-by-level %) timbre/levels-ordered)
|
||||
(every? #(and (integer? %) (<= 0 % 100000)) (vals nentries-by-level))]}
|
||||
|
@ -58,7 +59,7 @@
|
|||
nmax-entries (nentries-by-level level)]
|
||||
|
||||
(when (> nmax-entries 0)
|
||||
(car/wcar conn
|
||||
(car/wcar (or conn-opts (:conn opts)) ; :conn is Deprecated
|
||||
(binding [nippy/*final-freeze-fallback* nippy/freeze-fallback-as-str]
|
||||
(car/hset k-hash entry-hash entry))
|
||||
(car/zadd k-zset udt entry-hash)
|
||||
|
@ -89,7 +90,7 @@
|
|||
Returns latest `n` log entries by level as an ordered vector of deserialized
|
||||
maps. Normal sequence fns can be used to query/transform entries. Datomic and
|
||||
core.logic are also useful!"
|
||||
[conn level & [n asc? keyfn]]
|
||||
[conn-opts level & [n asc? keyfn]]
|
||||
{:pre [(or (nil? n) (and (integer? n) (<= 1 n 100000)))]}
|
||||
(let [keyfn (or keyfn default-keyfn)
|
||||
k-zset (keyfn (name level))
|
||||
|
@ -97,7 +98,7 @@
|
|||
|
||||
entries-zset ; [{:hash _ :level _ :instant _} ...]
|
||||
(->>
|
||||
(car/wcar conn
|
||||
(car/wcar conn-opts
|
||||
(if asc? (car/zrange k-zset 0 (if n (dec n) -1) :withscores)
|
||||
(car/zrevrange k-zset 0 (if n (dec n) -1) :withscores)))
|
||||
(partition 2) ; Reconstitute :level, :instant keys:
|
||||
|
@ -109,9 +110,9 @@
|
|||
|
||||
entries-hash ; [{_}-or-ex {_}-or-ex ...]
|
||||
(when-let [hashes (seq (mapv :hash entries-zset))]
|
||||
(if-not (next hashes)
|
||||
(car/wcar conn :as-pipeline (apply car/hget k-hash hashes)) ; Careful!
|
||||
(car/wcar conn (apply car/hmget k-hash hashes))))]
|
||||
(if-not (next hashes) ; Careful!
|
||||
(car/wcar conn-opts :as-pipeline (apply car/hget k-hash hashes))
|
||||
(car/wcar conn-opts (apply car/hmget k-hash hashes))))]
|
||||
|
||||
(mapv (fn [m1 m2-or-ex]
|
||||
(if (instance? Exception m2-or-ex)
|
||||
|
|
|
@ -64,8 +64,7 @@
|
|||
:pattern :daily})
|
||||
path: logfile path
|
||||
pattern: frequency of rotation, avialable values: :daily (default), :weekly, :monthly"
|
||||
[& [appender-opts {:keys [path pattern]
|
||||
:or {pattern :daily}}]]
|
||||
(let [default-appender-opts {:enabled? true :min-level nil}]
|
||||
[& [appender-opts]]
|
||||
(let [default-appender-opts {:enabled? true :min-level nil :pattern :daily}]
|
||||
(merge default-appender-opts appender-opts
|
||||
{:fn appender-fn})))
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
(.renameTo (io/file log) (io/file (format "%s.%03d" abs-path n)))
|
||||
(recur more (dec n))))))
|
||||
|
||||
(defn appender-fn [{:keys [ap-config prefix throwable message]}]
|
||||
(defn appender-fn [{:keys [ap-config output]}]
|
||||
(let [{:keys [path max-size backlog]
|
||||
:or {max-size (* 1024 1024)
|
||||
backlog 5}} (:rotor ap-config)]
|
||||
|
@ -61,9 +61,7 @@
|
|||
(when (> (.length (io/file path)) max-size)
|
||||
(rotate-logs path backlog))
|
||||
(spit path
|
||||
(with-out-str
|
||||
(t/str-println prefix "-" message
|
||||
(t/stacktrace throwable)))
|
||||
(str output "\n")
|
||||
:append true)
|
||||
(catch java.io.IOException _)))))
|
||||
|
||||
|
|
|
@ -2,24 +2,33 @@
|
|||
"Logging profiler for Timbre, adapted from clojure.contrib.profile."
|
||||
{:author "Peter Taoussanis"}
|
||||
(:require [clojure.tools.macro :as macro]
|
||||
[taoensso.timbre :as timbre]
|
||||
[taoensso.timbre.utils :as utils]))
|
||||
[taoensso.encore :as encore]
|
||||
[taoensso.timbre :as timbre]))
|
||||
|
||||
(def ^:dynamic *pdata* "{::pname [time1 time2 ...]}" nil)
|
||||
(defmacro fq-keyword "Returns namespaced keyword for given id."
|
||||
[id]
|
||||
`(if (and (keyword? ~id) (namespace ~id)) ~id
|
||||
(keyword (str ~*ns*) (name ~id))))
|
||||
|
||||
(comment (map #(fq-keyword %) ["foo" :foo :foo/bar]))
|
||||
|
||||
(def ^:dynamic *pdata* "{::pid [time1 time2 ...]}" nil)
|
||||
|
||||
(defn pspy* [id f]
|
||||
(if-not *pdata* (f)
|
||||
(let [id (fq-keyword id)
|
||||
t0 (System/nanoTime)]
|
||||
(try (f)
|
||||
(finally
|
||||
(let [t-elapsed (- (System/nanoTime) t0)]
|
||||
(swap! *pdata* #(assoc % id (conj (% id []) t-elapsed)))))))))
|
||||
|
||||
(defmacro pspy
|
||||
"Profile spy. When in the context of a *pdata* binding, records execution time
|
||||
of named body. Always returns the body's result."
|
||||
[name & body]
|
||||
`(if-not *pdata* (do ~@body)
|
||||
(let [name# (utils/fq-keyword ~name)
|
||||
start-time# (System/nanoTime)]
|
||||
(try (do ~@body)
|
||||
(finally
|
||||
(let [elapsed# (- (System/nanoTime) start-time#)]
|
||||
(swap! *pdata* #(assoc % name# (conj (% name# []) elapsed#)))))))))
|
||||
[id & body] `(pspy* ~id (fn [] ~@body)))
|
||||
|
||||
(defmacro p [name & body] `(pspy ~name ~@body)) ; Alias
|
||||
(defmacro p [id & body] `(pspy ~id ~@body)) ; Alias
|
||||
|
||||
(declare pdata-stats format-pdata)
|
||||
|
||||
|
@ -38,66 +47,66 @@
|
|||
Note that logging appenders will receive both a formatted profiling string AND
|
||||
the raw profiling stats under a special :profiling-stats key (useful for
|
||||
queryable db logging)."
|
||||
[level name & body]
|
||||
[level id & body]
|
||||
`(let [{result# :result stats# :stats} (with-pdata ~level ~@body)]
|
||||
(when stats#
|
||||
(timbre/log* {:profile-stats stats#} :format ~level
|
||||
"Profiling: %s\n%s" (utils/fq-keyword ~name)
|
||||
"Profiling: %s\n%s" (fq-keyword ~id)
|
||||
(format-pdata stats#)))
|
||||
result#))
|
||||
|
||||
(defmacro sampling-profile
|
||||
"Like `profile`, but only enables profiling with given probability."
|
||||
[level probability name & body]
|
||||
[level probability id & body]
|
||||
`(do (assert (<= 0 ~probability 1) "Probability: 0<=p<=1")
|
||||
(if-not (< (rand) ~probability) (do ~@body)
|
||||
(profile ~level ~name ~@body))))
|
||||
(profile ~level ~id ~@body))))
|
||||
|
||||
(defn pdata-stats
|
||||
"{::pname [time1 time2 ...] ...} => {::pname {:min <min-time> ...} ...}
|
||||
"{::pid [time1 time2 ...] ...} => {::pid {:min <min-time> ...} ...}
|
||||
For performance, stats are calculated once only after all data have been
|
||||
collected."
|
||||
[pdata]
|
||||
(reduce-kv
|
||||
(fn [m pname times]
|
||||
(fn [m pid times]
|
||||
(let [count (max 1 (count times))
|
||||
time (reduce + times)
|
||||
mean (long (/ time count))
|
||||
mad (long (/ (reduce + (map #(Math/abs (long (- % mean)))
|
||||
times)) ; Mean absolute deviation
|
||||
count))]
|
||||
(assoc m pname {:count count
|
||||
:min (apply min times)
|
||||
:max (apply max times)
|
||||
:mean mean
|
||||
:mad mad
|
||||
:time time})))
|
||||
(assoc m pid {:count count
|
||||
:min (apply min times)
|
||||
:max (apply max times)
|
||||
:mean mean
|
||||
:mad mad
|
||||
:time time})))
|
||||
{} (or pdata {})))
|
||||
|
||||
(defn format-pdata [stats & [sort-field]]
|
||||
(let [clock-time (-> stats ::clock-time :time) ; How long entire profile body took
|
||||
stats (dissoc stats ::clock-time)
|
||||
accounted (reduce + (map :time (vals stats)))
|
||||
max-name-width (apply max (map (comp count str)
|
||||
(conj (keys stats) "Accounted Time")))
|
||||
pattern (str "%" max-name-width "s %6d %9s %10s %9s %9s %7d %1s%n")
|
||||
stats (dissoc stats ::clock-time)
|
||||
accounted (reduce + (map :time (vals stats)))
|
||||
max-id-width (apply max (map (comp count str)
|
||||
(conj (keys stats) "Accounted Time")))
|
||||
pattern (str "%" max-id-width "s %6d %9s %10s %9s %9s %7d %1s%n")
|
||||
s-pattern (.replace pattern \d \s)
|
||||
perc #(Math/round (/ %1 %2 0.01))
|
||||
ft (fn [nanosecs]
|
||||
(let [pow #(Math/pow 10 %)
|
||||
ok-pow? #(>= nanosecs (pow %))
|
||||
to-pow #(utils/round-to %2 (/ nanosecs (pow %1)))]
|
||||
to-pow #(encore/round (/ nanosecs (pow %1)) :round %2)]
|
||||
(cond (ok-pow? 9) (str (to-pow 9 1) "s")
|
||||
(ok-pow? 6) (str (to-pow 6 0) "ms")
|
||||
(ok-pow? 3) (str (to-pow 3 0) "μs")
|
||||
:else (str nanosecs "ns"))))]
|
||||
|
||||
(with-out-str
|
||||
(printf s-pattern "Name" "Calls" "Min" "Max" "MAD" "Mean" "Time%" "Time")
|
||||
(doseq [pname (->> (keys stats)
|
||||
(sort-by #(- (get-in stats [% (or sort-field :time)]))))]
|
||||
(let [{:keys [count min max mean mad time]} (stats pname)]
|
||||
(printf pattern pname count (ft min) (ft max) (ft mad)
|
||||
(printf s-pattern "Id" "Calls" "Min" "Max" "MAD" "Mean" "Time%" "Time")
|
||||
(doseq [pid (->> (keys stats)
|
||||
(sort-by #(- (get-in stats [% (or sort-field :time)]))))]
|
||||
(let [{:keys [count min max mean mad time]} (stats pid)]
|
||||
(printf pattern pid count (ft min) (ft max) (ft mad)
|
||||
(ft mean) (perc time clock-time) (ft time))))
|
||||
|
||||
(printf s-pattern "Clock Time" "" "" "" "" "" 100 (ft clock-time))
|
||||
|
@ -107,7 +116,7 @@
|
|||
(defmacro defnp "Like `defn` but wraps body in `p` macro."
|
||||
{:arglists '([name ?doc-string ?attr-map [params] ?prepost-map body])}
|
||||
[name & sigs]
|
||||
(let [[name [params & sigs]] (macro/name-with-attributes name sigs)
|
||||
(let [[name [params & sigs]] (encore/name-with-attrs name sigs)
|
||||
prepost-map (when (and (map? (first sigs)) (next sigs)) (first sigs))
|
||||
body (if prepost-map (next sigs) sigs)]
|
||||
`(defn ~name ~params ~prepost-map
|
||||
|
@ -120,14 +129,14 @@
|
|||
|
||||
(comment
|
||||
(profile :info :sleepy-threads
|
||||
(dotimes [n 5]
|
||||
(Thread/sleep 100) ; Unaccounted
|
||||
(p :1ms (Thread/sleep 1))
|
||||
(p :2s (Thread/sleep 2000))
|
||||
(p :50ms (Thread/sleep 50))
|
||||
(p :rand (Thread/sleep (if (> 0.5 (rand)) 10 500)))
|
||||
(p :10ms (Thread/sleep 10))
|
||||
"Result"))
|
||||
(dotimes [n 5]
|
||||
(Thread/sleep 100) ; Unaccounted
|
||||
(p :1ms (Thread/sleep 1))
|
||||
(p :2s (Thread/sleep 2000))
|
||||
(p :50ms (Thread/sleep 50))
|
||||
(p :rand (Thread/sleep (if (> 0.5 (rand)) 10 500)))
|
||||
(p :10ms (Thread/sleep 10))
|
||||
"Result"))
|
||||
|
||||
(p :hello "Hello, this is a result") ; Falls through (no *pdata* context)
|
||||
|
||||
|
|
|
@ -1,109 +1,2 @@
|
|||
(ns taoensso.timbre.utils
|
||||
{:author "Peter Taoussanis"}
|
||||
(:require [clojure.tools.macro :as macro]))
|
||||
|
||||
(defmacro defonce*
|
||||
"Like `clojure.core/defonce` but supports optional docstring and attributes
|
||||
map for name symbol."
|
||||
{:arglists '([name expr])}
|
||||
[name & sigs]
|
||||
(let [[name [expr]] (macro/name-with-attributes name sigs)]
|
||||
`(clojure.core/defonce ~name ~expr)))
|
||||
|
||||
(defn memoize-ttl "Low-overhead, common-case `memoize*`."
|
||||
[ttl-ms f]
|
||||
(let [cache (atom {})]
|
||||
(fn [& args]
|
||||
(when (<= (rand) 0.001) ; GC
|
||||
(let [instant (System/currentTimeMillis)]
|
||||
(swap! cache
|
||||
(fn [m] (reduce-kv (fn [m* k [dv udt :as cv]]
|
||||
(if (> (- instant udt) ttl-ms) m*
|
||||
(assoc m* k cv))) {} m)))))
|
||||
(let [[dv udt] (@cache args)]
|
||||
(if (and dv (< (- (System/currentTimeMillis) udt) ttl-ms)) @dv
|
||||
(locking cache ; For thread racing
|
||||
(let [[dv udt] (@cache args)] ; Retry after lock acquisition!
|
||||
(if (and dv (< (- (System/currentTimeMillis) udt) ttl-ms)) @dv
|
||||
(let [dv (delay (apply f args))
|
||||
cv [dv (System/currentTimeMillis)]]
|
||||
(swap! cache assoc args cv)
|
||||
@dv)))))))))
|
||||
|
||||
(defn rate-limiter
|
||||
"Returns a `(fn [& [id]])` that returns either `nil` (limit okay) or number of
|
||||
msecs until next rate limit window (rate limited)."
|
||||
[ncalls-limit window-ms]
|
||||
(let [state (atom [nil {}])] ; [<pull> {<id> {[udt-window-start ncalls]}}]
|
||||
(fn [& [id]]
|
||||
|
||||
(when (<= (rand) 0.001) ; GC
|
||||
(let [instant (System/currentTimeMillis)]
|
||||
(swap! state
|
||||
(fn [[_ m]]
|
||||
[nil (reduce-kv
|
||||
(fn [m* id [udt-window-start ncalls]]
|
||||
(if (> (- instant udt-window-start) window-ms) m*
|
||||
(assoc m* id [udt-window-start ncalls]))) {} m)]))))
|
||||
|
||||
(->
|
||||
(let [instant (System/currentTimeMillis)]
|
||||
(swap! state
|
||||
(fn [[_ m]]
|
||||
(if-let [[udt-window-start ncalls] (m id)]
|
||||
(if (> (- instant udt-window-start) window-ms)
|
||||
[nil (assoc m id [instant 1])]
|
||||
(if (< ncalls ncalls-limit)
|
||||
[nil (assoc m id [udt-window-start (inc ncalls)])]
|
||||
[(- (+ udt-window-start window-ms) instant) m]))
|
||||
[nil (assoc m id [instant 1])]))))
|
||||
(nth 0)))))
|
||||
|
||||
(comment
|
||||
(def rl (rate-limit 10 10000))
|
||||
(repeatedly 10 #(rl (rand-nth [:a :b :c])))
|
||||
(rl :a)
|
||||
(rl :b)
|
||||
(rl :c))
|
||||
|
||||
(defn merge-deep-with ; From clojure.contrib.map-utils
|
||||
"Like `merge-with` but merges maps recursively, applying the given fn
|
||||
only when there's a non-map at a particular level.
|
||||
|
||||
(merge-deep-with + {:a {:b {:c 1 :d {:x 1 :y 2}} :e 3} :f 4}
|
||||
{:a {:b {:c 2 :d {:z 9} :z 3} :e 100}})
|
||||
=> {:a {:b {:z 3, :c 3, :d {:z 9, :x 1, :y 2}}, :e 103}, :f 4}"
|
||||
[f & maps]
|
||||
(apply
|
||||
(fn m [& maps]
|
||||
(if (every? map? maps)
|
||||
(apply merge-with m maps)
|
||||
(apply f maps)))
|
||||
maps))
|
||||
|
||||
(def merge-deep (partial merge-deep-with (fn [x y] y)))
|
||||
|
||||
(comment (merge-deep {:a {:b {:c {:d :D :e :E}}}}
|
||||
{:a {:b {:g :G :c {:c {:f :F}}}}}))
|
||||
|
||||
(defn round-to "Rounds argument to given number of decimal places."
|
||||
[places x]
|
||||
(if (zero? places)
|
||||
(Math/round (double x))
|
||||
(let [modifier (Math/pow 10.0 places)]
|
||||
(/ (Math/round (* x modifier)) modifier))))
|
||||
|
||||
(comment (round-to 0 10)
|
||||
(round-to 2 10.123))
|
||||
|
||||
(defmacro fq-keyword "Returns namespaced keyword for given name."
|
||||
[name]
|
||||
`(if (and (keyword? ~name) (namespace ~name)) ~name
|
||||
(keyword (str ~*ns*) (clojure.core/name ~name))))
|
||||
|
||||
(comment (map #(fq-keyword %) ["foo" :foo :foo/bar]))
|
||||
|
||||
(defmacro sometimes "Executes body with probability e/o [0,1]."
|
||||
[probability & body]
|
||||
`(do (assert (<= 0 ~probability 1) "Probability: 0 <= p <= 1")
|
||||
(when (< (rand) ~probability) ~@body)))
|
||||
{:author "Peter Taoussanis"})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(ns taoensso.timbre.tests.main
|
||||
(:require [expectations :as test :refer :all]
|
||||
[taoensso.timbre :as timbre :refer (trace debug info warn
|
||||
error fatal spy)]
|
||||
[taoensso.timbre.profiling :as profiling :refer (p profile)]))
|
||||
[taoensso.timbre :as timbre]))
|
||||
|
||||
(timbre/refer-timbre)
|
||||
|
||||
(defn- before-run {:expectations-options :before-run} [])
|
||||
(defn- after-run {:expectations-options :after-run} [])
|
||||
|
|
Loading…
Reference in New Issue