69162083cd5eb717d21c1706165ae4c64388d775
[bpt/coccinelle.git] / bundles / pycaml / chemoelectric-pycaml-8614105 / examples / log.ml
1 #use "topfind";;
2 #require "pycaml";;
3 #require "snippets";;
4
5 open Pycaml;;
6
7 (* See http://docs.python.org/lib/module-logging.html for Level values *)
8 type logging_levels = Notset | Debug | Info | Warn | Error | Critical | Level of int;;
9
10 (* Set default logger *)
11 let default_logger = (fun l m -> Printf.printf "ocaml-default log: %d %s%!\n%!" l m);;
12
13 let loggers = Hashtbl.create 10;;
14 Hashtbl.add loggers "default-ocaml" default_logger;;
15
16 (* Translate level names into numerical values as used by Python
17 See http://docs.python.org/lib/module-logging.html for Level values *)
18 let int_of_level name =
19 match name with
20 | Notset -> 0
21 | Debug -> 10
22 | Info -> 20
23 | Warn -> 30
24 | Error -> 40
25 | Critical -> 50
26 | Level (n)-> n
27 ;;
28
29 let find_logger name =
30 try
31 Hashtbl.find loggers name
32 with
33 | Not_found ->
34 try
35 Hashtbl.find loggers "default-ocaml"
36 with
37 | Not_found -> failwith "Default logger missing -- internal problem";;
38
39
40 (* Provide interface functions as in Python's logging module *)
41 let debug name msg =
42 let log = find_logger name in
43 log (int_of_level Debug) msg;;
44
45 let info name msg =
46 let log = find_logger name in
47 log (int_of_level Info) msg;;
48
49 let warn name msg =
50 let log = find_logger name in
51 log (int_of_level Warn) msg;;
52
53 let warning = warn;;
54
55 let error name msg =
56 let log = find_logger name in
57 log (int_of_level Error) msg;;
58
59 let critical name msg =
60 let log = find_logger name in
61 log (int_of_level Critical) msg;;
62
63 (* Function that takes a name, level integer (this is 'raw') and the message *)
64 let lograw name level msg =
65 let logf = find_logger name in
66 logf level msg;;
67
68 (* Function that takes a name, level and the message.
69 Presumably, this is what will be used most often. *)
70 let log name level msg =
71 let lograw = find_logger name in
72 lograw (int_of_level level) msg;;
73
74
75 (* Allowing to register loggers from Python *)
76
77 let add_logger_if_new name logger =
78 let loggername =
79 try
80 let _ = Str.search_forward (Str.regexp "ocaml") name 0 in
81 name
82 with
83 | Not_found -> Printf.sprintf "%s-ocaml" name
84 in
85 try
86 let _ = Hashtbl.find loggers loggername
87 in failwith (Printf.sprintf "Trying to register logger '%s' again. Why?" loggername)
88 with
89 | Not_found -> Printf.printf "Adding logger %s to hashtable\n%!" loggername;
90 Hashtbl.add loggers loggername logger;;
91
92 let _py_register_logger =
93 python_pre_interfaced_function
94 ~doc:"Register a python-logger. \nArguments: Logger name (str) and callback function cb(). \nThe signature of cb() is cb( level: int, message:str). "
95 [|StringType;CallableType|]
96 (fun py_args ->
97 let name = pystring_asstring py_args.(0) in
98 let ocamllogger = (fun level msg ->
99 let callback_args =
100 pytuple_fromarray
101 [|pyint_fromint level;
102 pystring_fromstring msg|]
103 in
104 let _ = pyeval_callobject(py_args.(1),callback_args) in ()
105 )
106 in let () = add_logger_if_new name ocamllogger
107 in pynone() );;
108
109
110
111
112
113 (* Debugging tools: *)
114
115 (* getinfo returns an array of strings that contain the names of registered loggers. *)
116 let getinfo loggers =
117 let loggerarray = Array.make (Hashtbl.length loggers) "empty" in
118 let () = Snippets.hashtbl_iteri (fun i key value -> (loggerarray.(i) <- key)) loggers in
119 loggerarray;;
120
121 let print_loggers loggers =
122 Array.iter (fun a -> Printf.printf "registered loggername=%s\n%!" a) (getinfo loggers);;
123
124 let _py_ocaml_log =
125 python_pre_interfaced_function
126 ~doc: "Function that calls the ocaml logger from Python (just for debugging useful) "
127 [|StringType;IntType;StringType|] ( fun py_args ->
128 let name = pystring_asstring py_args.(0) in
129 let level = pyint_asint py_args.(1) in
130 let msg = pystring_asstring py_args.(2) in
131 let () = lograw name level msg in
132 pynone() );;
133
134 (* Register function for Python *)
135
136 let () = register_pre_functions_for_python
137 [| ("log", _py_ocaml_log);
138 ("register_logger", _py_register_logger) |]
139 ;;
140
141
142
143 (* This needs to go into the documentation *)
144
145 Printf.printf "About to start tests (Ocaml)\n";;
146
147 let () = add_logger_if_new "Ocaml" (fun l m -> Printf.printf "Ocamllog, Lev=%d: %s\n" l m);
148
149 python_load "log.py";;
150
151 log "default" (Level 30) "Purely called from Ocaml";;
152
153 info "ocaml" "This is information";;
154
155 print_loggers loggers;;
156
157 python_eval "logger.warn('Warning from Python')";;
158
159 let nmeshlog = log
160 (* ipython();; *)
161