Skip to content

Commit 74adf85

Browse files
authored
Simple logger (#134)
* define casbin's own rhai package * remove transparent error to make casbin error explicit * implement TryIntoAdapter for () * add simple logger * improve format * bump version * add mgmt log * disable logging by default for better performance * fix clippy warnings
1 parent 84a9d0f commit 74adf85

16 files changed

Lines changed: 400 additions & 205 deletions

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "casbin"
3-
version = "0.6.2"
3+
version = "0.7.0"
44
authors = ["Joey <joey.xf@gmail.com>", "Cheng JIANG <jiang.cheng@vip.163.com>"]
55
edition = "2018"
66
license = "Apache-2.0"
@@ -27,7 +27,7 @@ globset = "0.4.5"
2727
thiserror = "1.0.14"
2828

2929
[features]
30-
default = ["runtime-async-std", "logging"]
30+
default = ["runtime-async-std"]
3131

3232
runtime-tokio = ["tokio/fs", "tokio/io-util", "tokio/stream", "tokio/rt-threaded", "tokio/blocking"]
3333
runtime-async-std = ["async-std"]

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ Add this package to `Cargo.toml` of your project. (Check https://crates.io/crate
2727

2828
```toml
2929
[dependencies]
30-
casbin = "0.6.2"
30+
casbin = { version = "0.7.0", default-features = false, features = ["runtime-async-std", "logging"] }
3131
async-std = { version = "1.5.0", features = ["attributes"] }
32+
env_logger = "0.7.1"
3233
```
3334

3435
## Get started
@@ -41,7 +42,13 @@ use casbin::prelude::*;
4142

4243
#[async_std::main]
4344
async fn main() -> Result<()> {
44-
let mut e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
45+
::std::env::set_var("RUST_LOG", "casbin=info");
46+
env_logger::init();
47+
48+
let mut e = Enforcer::new("examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv").await?;
49+
e.enable_log(true);
50+
51+
e.enforce(&["alice", "domain1", "data1", "read"]).await?;
4552
Ok(())
4653
}
4754
```

benches/benchmark.rs

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,7 @@ fn b_benchmark_cached_rbac_model(b: &mut Bencher) {
104104

105105
#[bench]
106106
fn b_benchmark_rbac_model_small(b: &mut Bencher) {
107-
let mut e = await_future(Enforcer::new(
108-
"examples/rbac_model.conf",
109-
None as Option<&str>,
110-
))
111-
.unwrap();
107+
let mut e = await_future(Enforcer::new("examples/rbac_model.conf", ())).unwrap();
112108

113109
e.enable_auto_build_role_links(false);
114110

@@ -145,11 +141,7 @@ fn b_benchmark_rbac_model_small(b: &mut Bencher) {
145141

146142
#[bench]
147143
fn b_benchmark_cached_rbac_model_small(b: &mut Bencher) {
148-
let mut e = await_future(CachedEnforcer::new(
149-
"examples/rbac_model.conf",
150-
None as Option<&str>,
151-
))
152-
.unwrap();
144+
let mut e = await_future(CachedEnforcer::new("examples/rbac_model.conf", ())).unwrap();
153145

154146
e.enable_auto_build_role_links(false);
155147

@@ -186,11 +178,7 @@ fn b_benchmark_cached_rbac_model_small(b: &mut Bencher) {
186178

187179
#[bench]
188180
fn b_benchmark_rbac_model_medium(b: &mut Bencher) {
189-
let mut e = await_future(Enforcer::new(
190-
"examples/rbac_model.conf",
191-
None as Option<&str>,
192-
))
193-
.unwrap();
181+
let mut e = await_future(Enforcer::new("examples/rbac_model.conf", ())).unwrap();
194182

195183
e.enable_auto_build_role_links(false);
196184

@@ -227,11 +215,7 @@ fn b_benchmark_rbac_model_medium(b: &mut Bencher) {
227215

228216
#[bench]
229217
fn b_benchmark_cached_rbac_model_medium(b: &mut Bencher) {
230-
let mut e = await_future(CachedEnforcer::new(
231-
"examples/rbac_model.conf",
232-
None as Option<&str>,
233-
))
234-
.unwrap();
218+
let mut e = await_future(CachedEnforcer::new("examples/rbac_model.conf", ())).unwrap();
235219

236220
e.enable_auto_build_role_links(false);
237221

@@ -268,11 +252,7 @@ fn b_benchmark_cached_rbac_model_medium(b: &mut Bencher) {
268252

269253
#[bench]
270254
fn b_benchmark_rbac_model_large(b: &mut Bencher) {
271-
let mut e = await_future(Enforcer::new(
272-
"examples/rbac_model.conf",
273-
None as Option<&str>,
274-
))
275-
.unwrap();
255+
let mut e = await_future(Enforcer::new("examples/rbac_model.conf", ())).unwrap();
276256

277257
e.enable_auto_build_role_links(false);
278258

@@ -309,11 +289,7 @@ fn b_benchmark_rbac_model_large(b: &mut Bencher) {
309289

310290
#[bench]
311291
fn b_benchmark_cached_rbac_model_large(b: &mut Bencher) {
312-
let mut e = await_future(CachedEnforcer::new(
313-
"examples/rbac_model.conf",
314-
None as Option<&str>,
315-
))
316-
.unwrap();
292+
let mut e = await_future(CachedEnforcer::new("examples/rbac_model.conf", ())).unwrap();
317293

318294
e.enable_auto_build_role_links(false);
319295

@@ -394,22 +370,14 @@ fn b_benchmark_cached_rbac_model_with_domains(b: &mut Bencher) {
394370

395371
#[bench]
396372
fn b_benchmark_abac_model(b: &mut Bencher) {
397-
let e = await_future(Enforcer::new(
398-
"examples/abac_model.conf",
399-
None as Option<&str>,
400-
))
401-
.unwrap();
373+
let e = await_future(Enforcer::new("examples/abac_model.conf", ())).unwrap();
402374

403375
b.iter(|| await_future(e.enforce(&["alice", r#"{"Owner": "alice"}"#, "read"])).unwrap());
404376
}
405377

406378
#[bench]
407379
fn b_benchmark_cached_abac_model(b: &mut Bencher) {
408-
let mut e = await_future(CachedEnforcer::new(
409-
"examples/abac_model.conf",
410-
None as Option<&str>,
411-
))
412-
.unwrap();
380+
let mut e = await_future(CachedEnforcer::new("examples/abac_model.conf", ())).unwrap();
413381

414382
b.iter(|| await_future(e.enforce_mut(&["alice", r#"{"Owner": "alice"}"#, "read"])).unwrap());
415383
}

src/cached_enforcer.rs

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ use crate::{
1313
Result,
1414
};
1515

16+
#[cfg(feature = "logging")]
17+
use crate::Logger;
18+
1619
use async_trait::async_trait;
1720

1821
use std::{
@@ -21,7 +24,7 @@ use std::{
2124
time::Duration,
2225
};
2326

24-
type EventCallback = fn(&mut CachedEnforcer, Option<EventData>);
27+
type EventCallback = fn(&mut CachedEnforcer, EventData);
2528

2629
pub struct CachedEnforcer {
2730
pub(crate) enforcer: Enforcer,
@@ -30,15 +33,15 @@ pub struct CachedEnforcer {
3033
}
3134

3235
impl EventEmitter<Event> for CachedEnforcer {
33-
fn on(&mut self, e: Event, f: fn(&mut Self, Option<EventData>)) {
36+
fn on(&mut self, e: Event, f: fn(&mut Self, EventData)) {
3437
self.events.entry(e).or_insert_with(Vec::new).push(f)
3538
}
3639

3740
fn off(&mut self, e: Event) {
3841
self.events.remove(&e);
3942
}
4043

41-
fn emit(&mut self, e: Event, d: Option<EventData>) {
44+
fn emit(&mut self, e: Event, d: EventData) {
4245
if let Some(cbs) = self.events.get(&e) {
4346
for cb in cbs.clone().iter() {
4447
cb(self, d.clone())
@@ -59,7 +62,7 @@ impl CoreApi for CachedEnforcer {
5962
events: HashMap::new(),
6063
};
6164

62-
cached_enforcer.on(Event::PolicyChange, clear_cache);
65+
cached_enforcer.on(Event::ClearCache, clear_cache);
6366

6467
Ok(cached_enforcer)
6568
}
@@ -128,21 +131,61 @@ impl CoreApi for CachedEnforcer {
128131
self.enforcer.set_adapter(a).await
129132
}
130133

134+
#[cfg(feature = "logging")]
135+
#[inline]
136+
fn get_logger(&self) -> &dyn Logger {
137+
self.enforcer.get_logger()
138+
}
139+
140+
#[cfg(feature = "logging")]
141+
#[inline]
142+
fn set_logger(&mut self, l: Box<dyn Logger>) {
143+
self.enforcer.set_logger(l);
144+
}
145+
131146
#[inline]
132147
fn set_effector(&mut self, e: Box<dyn Effector>) {
133148
self.enforcer.set_effector(e);
134149
}
135150

136151
async fn enforce_mut<S: AsRef<str> + Send + Sync>(&mut self, rvals: &[S]) -> Result<bool> {
137152
let key: Vec<String> = rvals.iter().map(|x| String::from(x.as_ref())).collect();
153+
#[allow(unused_variables)]
154+
let log_enabled = {
155+
#[cfg(feature = "logging")]
156+
{
157+
if self.enforcer.get_logger().is_enabled() {
158+
self.enforcer.enable_log(false);
159+
true
160+
} else {
161+
false
162+
}
163+
}
138164

139-
if let Some(result) = self.cache.get(&key).await {
140-
Ok(*result)
165+
#[cfg(not(feature = "logging"))]
166+
{
167+
false
168+
}
169+
};
170+
171+
#[allow(unused_variables)]
172+
let (res, is_cached) = if let Some(result) = self.cache.get(&key).await {
173+
(*result, true)
141174
} else {
142175
let result = self.enforcer.enforce(rvals).await?;
143-
self.cache.set(key, result).await;
144-
Ok(result)
176+
self.cache.set(key.clone(), result).await;
177+
(result, false)
178+
};
179+
180+
#[cfg(feature = "logging")]
181+
{
182+
self.enforcer.enable_log(log_enabled);
183+
self.enforcer
184+
.get_logger()
185+
.print_enforce_log(key, res, is_cached);
145186
}
187+
188+
Ok(res)
146189
}
147190

148191
/// CachedEnforcer should use `enforce_mut` instead so that
@@ -181,6 +224,12 @@ impl CoreApi for CachedEnforcer {
181224
self.enforcer.clear_policy();
182225
}
183226

227+
#[cfg(feature = "logging")]
228+
#[inline]
229+
fn enable_log(&mut self, enabled: bool) {
230+
self.enforcer.enable_log(enabled);
231+
}
232+
184233
#[inline]
185234
fn enable_enforce(&mut self, enabled: bool) {
186235
self.enforcer.enable_enforce(enabled);

src/convert.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ where
5454
}
5555
}
5656

57+
#[allow(clippy::unit_arg)]
58+
#[async_trait]
59+
impl TryIntoAdapter for () {
60+
async fn try_into_adapter(self) -> Result<Box<dyn Adapter>> {
61+
Ok(Box::new(NullAdapter))
62+
}
63+
}
64+
5765
#[async_trait]
5866
impl<T> TryIntoModel for T
5967
where

src/core_api.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ use crate::{
22
Adapter, Effector, Filter, Model, Result, RoleManager, TryIntoAdapter, TryIntoModel, Watcher,
33
};
44

5+
#[cfg(feature = "logging")]
6+
use crate::Logger;
7+
58
use async_trait::async_trait;
69

710
use std::sync::{Arc, RwLock};
@@ -19,6 +22,10 @@ pub trait CoreApi: Sized + Send + Sync {
1922
fn get_mut_watcher(&mut self) -> Option<&mut dyn Watcher>;
2023
fn get_role_manager(&self) -> Arc<RwLock<dyn RoleManager>>;
2124
fn set_role_manager(&mut self, rm: Arc<RwLock<dyn RoleManager>>) -> Result<()>;
25+
#[cfg(feature = "logging")]
26+
fn get_logger(&self) -> &dyn Logger;
27+
#[cfg(feature = "logging")]
28+
fn set_logger(&mut self, logger: Box<dyn Logger>);
2229
fn add_matching_fn(&mut self, f: fn(String, String) -> bool) -> Result<()>;
2330
async fn set_model<M: TryIntoModel>(&mut self, m: M) -> Result<()>;
2431
async fn set_adapter<A: TryIntoAdapter>(&mut self, a: A) -> Result<()>;
@@ -31,6 +38,8 @@ pub trait CoreApi: Sized + Send + Sync {
3138
fn is_filtered(&self) -> bool;
3239
async fn save_policy(&mut self) -> Result<()>;
3340
fn clear_policy(&mut self);
41+
#[cfg(feature = "logging")]
42+
fn enable_log(&mut self, enabled: bool);
3443
fn enable_auto_save(&mut self, auto_save: bool);
3544
fn enable_enforce(&mut self, enabled: bool);
3645
fn enable_auto_build_role_links(&mut self, auto_build_role_links: bool);

src/emitter.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::{cached_api::CachedApi, core_api::CoreApi};
22

3-
use std::hash::Hash;
3+
use std::{fmt, hash::Hash};
44

55
#[derive(Hash, PartialEq, Eq)]
66
pub enum Event {
77
PolicyChange,
8+
ClearCache,
89
}
910

1011
pub trait EventKey: Hash + PartialEq + Eq + Send + Sync {}
@@ -18,24 +19,47 @@ pub enum EventData {
1819
RemovePolicies(Vec<Vec<String>>),
1920
RemoveFilteredPolicy(Vec<Vec<String>>),
2021
SavePolicy(Vec<Vec<String>>),
22+
ClearCache,
23+
}
24+
25+
impl fmt::Display for EventData {
26+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27+
use EventData::*;
28+
match *self {
29+
AddPolicy(ref p) => write!(f, "Event: AddPolicy, Data: {:?}", p.join(", ")),
30+
AddPolicies(ref p) => write!(f, "Event: AddPolicies, Added: {}", p.len()),
31+
RemovePolicy(ref p) => write!(f, "Event: RemovePolicy, Data: {:?}", p.join(", ")),
32+
RemovePolicies(ref p) => write!(f, "Event: RemovePolicies, Removed: {}", p.len()),
33+
RemoveFilteredPolicy(ref p) => {
34+
write!(f, "Event: RemoveFilteredPolicy, Removed: {}", p.len())
35+
}
36+
SavePolicy(ref p) => write!(f, "Event: SavePolicy, Saved: {}", p.len()),
37+
ClearCache => write!(f, "Event: ClearCache, Data: ClearCache"),
38+
}
39+
}
2140
}
2241

2342
pub trait EventEmitter<K>
2443
where
2544
K: EventKey,
2645
{
27-
fn on(&mut self, e: K, f: fn(&mut Self, Option<EventData>));
46+
fn on(&mut self, e: K, f: fn(&mut Self, EventData));
2847
fn off(&mut self, e: K);
29-
fn emit(&mut self, e: K, d: Option<EventData>);
48+
fn emit(&mut self, e: K, d: EventData);
3049
}
3150

32-
pub(crate) fn notify_watcher<T: CoreApi>(e: &mut T, d: Option<EventData>) {
51+
pub(crate) fn notify_watcher<T: CoreApi>(e: &mut T, d: EventData) {
52+
#[cfg(feature = "logging")]
53+
{
54+
e.get_logger().print_mgmt_log(&d);
55+
}
56+
3357
if let Some(w) = e.get_mut_watcher() {
3458
w.update(d);
3559
}
3660
}
3761

38-
pub(crate) fn clear_cache<T: CoreApi + CachedApi>(ce: &mut T, _d: Option<EventData>) {
62+
pub(crate) fn clear_cache<T: CoreApi + CachedApi>(ce: &mut T, _d: EventData) {
3963
#[cfg(feature = "runtime-tokio")]
4064
{
4165
tokio::runtime::Builder::new()

0 commit comments

Comments
 (0)