├── LICENSE ├── README.md ├── katipviewer.html ├── shard.yml ├── spec ├── katip_spec.cr └── spec_helper.cr └── src ├── katip.cr └── katip ├── classextention └── file.cr ├── config.cr ├── core ├── app.cr ├── appender.cr ├── engine.cr └── enums.cr ├── exceptions ├── CanNotLogException.cr └── NotSetException.cr ├── info.cr ├── logger.cr └── version.cr /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Güven Cenan Güvenal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # katip 4 | 5 | Katip is Logger for Crystal 6 | 7 | ## Installation 8 | 9 | Add this to your application's `shard.yml`: 10 | 11 | ```yaml 12 | dependencies: 13 | katip: 14 | github: guvencenanguvenal/katip 15 | ``` 16 | 17 | ## Usage 18 | 19 | ```crystal 20 | require "katip" 21 | ``` 22 | 23 | Create your logger variable and configure it. 24 | 25 | ```crystal 26 | logger = Katip::Logger.new 27 | 28 | logger.configure do |config| 29 | config.loglevel = Katip::LogLevel::DEBUG 30 | config.logclassification = Katip::LogClassification::DATE_DAY 31 | config.path = "src/katip/logfiles" 32 | 33 | #### if you want to fill project's information 34 | config.info.description = "This is project description." 35 | config.info.project = "Module or project name." 36 | config.info.version = VERSION # project version 37 | end 38 | ``` 39 | 40 | And basic log it! 41 | 42 | ```crystal 43 | logger.debug("Debug mode is on!") 44 | 45 | logger.info("Information! This is log.") 46 | 47 | logger.warn("Warning! Please control your code.") 48 | 49 | logger.error("Error! Please fix and re-compile it!") 50 | 51 | logger.fatal("Fatal! OH NO!") 52 | ``` 53 | 54 | if you want log detail, you can use this methods. 55 | 56 | ```crystal 57 | logger.debug("Debug mode is on!", self, YourExceptionName) 58 | 59 | logger.info("Information! This is log.", self, YourExceptionName) 60 | 61 | logger.warn("Warning! Please control your code.", self, YourExceptionName) 62 | 63 | logger.error("Error! Please fix and re-compile it!", self, YourExceptionName) 64 | 65 | logger.fatal("Fatal! OH NO!", self, YourExceptionName) 66 | ``` 67 | 68 | ## JSON Output 69 | 70 | Please do not edit manual JSON log files! 71 | 72 | ```json 73 | { 74 | "katip":"0.1.0", 75 | "info":{ 76 | "description":"", 77 | "project":"", 78 | "version":""}, 79 | "errors":[ 80 | { "date":"2017-05-07 00:24:57 +0300", 81 | "class":"Class", 82 | "message":"Debug mode is on!", 83 | "exception_type":"Katip::NotSetException", 84 | "exception_message":"Not Init", 85 | "log_level":"DEBUG" 86 | } 87 | ] 88 | } 89 | ``` 90 | 91 | ## View Your Logs 92 | 93 | You can use katipviewer.html to control your logs. 94 | 95 | Open katipviewer.html on local machine. 96 | 97 | 98 | 99 | Choose your log json file. 100 | 101 | 102 | 103 | Click Read JSON Log button. 104 | 105 | 106 | 107 | 108 | ## Contributing 109 | 110 | 1. Fork it ( https://github.com/guvencenanguvenal/katip/fork ) 111 | 2. Create your feature branch (git checkout -b my-new-feature) 112 | 3. Commit your changes (git commit -am 'Add some feature') 113 | 4. Push to the branch (git push origin my-new-feature) 114 | 5. Create a new Pull Request 115 | 116 | ## Contributors 117 | 118 | - [guvencenanguvenal](https://github.com/guvencenanguvenal) Güven Cenan Güvenal - creator, maintainer 119 | -------------------------------------------------------------------------------- /katipviewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 85 | 86 | 87 |
88 |
89 |

Katip JSON Log Viewer

90 |
91 |
92 |
93 |
94 |
95 |
96 | 97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |

Contents of the file:

106 |

107 |                 
108 |
109 |
110 |
111 |
112 |
113 | 114 |
115 |
116 |
117 |
118 |
119 |
120 |
Katip
121 |
122 | 123 |
124 |
125 |
126 |
127 |
128 | 135 |
136 |
137 |

DEBUG

138 |

139 |
140 |
141 |

INFO

142 |

143 |
144 |
145 |

WARNING

146 |

147 |
148 |
149 |

ERROR

150 |

151 |
152 |
153 |

FATAL

154 |

155 |
156 |
157 |
158 |
159 |
160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /shard.yml: -------------------------------------------------------------------------------- 1 | name: katip 2 | version: 0.1.0 3 | 4 | authors: 5 | - Güven Cenan Güvenal 6 | 7 | crystal: 0.21.1 8 | 9 | license: MIT 10 | -------------------------------------------------------------------------------- /spec/katip_spec.cr: -------------------------------------------------------------------------------- 1 | require "./spec_helper" 2 | 3 | describe Katip do 4 | # TODO: Write tests 5 | 6 | it "works" do 7 | false.should eq(true) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/spec_helper.cr: -------------------------------------------------------------------------------- 1 | require "spec" 2 | require "../src/katip" 3 | -------------------------------------------------------------------------------- /src/katip.cr: -------------------------------------------------------------------------------- 1 | require "file" 2 | require "file_utils" 3 | require "json" 4 | 5 | require "./katip/exceptions/*" 6 | require "./katip/classextention/*" 7 | require "./katip/*" 8 | require "./katip/core/*" -------------------------------------------------------------------------------- /src/katip/classextention/file.cr: -------------------------------------------------------------------------------- 1 | require "file" 2 | 3 | class File 4 | def self.append(filename : String, text : String) 5 | File.open(filename, "r+") do |file| 6 | file.seek(0, IO::Seek::End) 7 | file.print(text) 8 | end 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /src/katip/config.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | class Config 3 | property loglevel = LogLevel::ALL 4 | property logclassification = LogClassification::DATE_DAY 5 | 6 | property path = "src/katipdeneme/logfiles" 7 | 8 | property info = Information.new 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/katip/core/app.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | module Core 3 | class App 4 | 5 | ### 6 | # 7 | ### 8 | private def init_app 9 | _file_path = @config.path.split("/") 10 | _file_path_next = "" 11 | 12 | _file_path.each do |path| 13 | if _file_path_next == "" 14 | _file_path_next = path 15 | else 16 | _file_path_next += "/" + path 17 | end 18 | 19 | if !File.directory?(_file_path_next) 20 | FileUtils.mkdir(_file_path_next) 21 | end 22 | end 23 | 24 | rescue ex 25 | puts "********************************************************" 26 | puts "Error until create directory please control your path!" 27 | puts "Path format must be;" 28 | puts "dir1/dir2/dir3..." 29 | puts "Your path is" 30 | puts @config.path 31 | puts "--------------------------------------------------------" 32 | puts ex.message 33 | puts "********************************************************" 34 | end 35 | 36 | def initialize(@config : Config) 37 | init_app 38 | 39 | @appender = Core::Appender.new(@config) 40 | 41 | # :TODO Create directories 42 | end 43 | 44 | def configure(@config : Config) 45 | init_app 46 | end 47 | 48 | ### 49 | # DEBUG 50 | # 51 | ### 52 | def debug_logger(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 53 | if @config.loglevel.value <= LogLevel::DEBUG.value 54 | # :TODO 55 | @appender.log(obj_class, text, ex, LogLevel::DEBUG) 56 | end 57 | 58 | rescue CanNotLogException 59 | puts "********************************************************" 60 | puts "Directories is created again!" 61 | init_app 62 | puts "Create is done!" 63 | puts "********************************************************" 64 | end 65 | 66 | ### 67 | # INFO 68 | # 69 | ### 70 | def info_logger(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 71 | if @config.loglevel.value <= LogLevel::INFO.value 72 | # :TODO 73 | @appender.log(obj_class, text, ex, LogLevel::INFO) 74 | end 75 | 76 | rescue CanNotLogException 77 | puts "********************************************************" 78 | puts "Directories is created again!" 79 | init_app 80 | puts "Create is done!" 81 | puts "********************************************************" 82 | end 83 | 84 | ### 85 | # WARN 86 | # 87 | ### 88 | def warn_logger(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 89 | if @config.loglevel.value <= LogLevel::WARN.value 90 | # :TODO 91 | @appender.log(obj_class, text, ex, LogLevel::WARN) 92 | end 93 | 94 | rescue CanNotLogException 95 | puts "********************************************************" 96 | puts "Directories is created again!" 97 | init_app 98 | puts "Create is done!" 99 | puts "********************************************************" 100 | end 101 | 102 | ### 103 | # ERROR 104 | # 105 | ### 106 | def error_logger(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 107 | if @config.loglevel.value <= LogLevel::ERROR.value 108 | # :TODO 109 | @appender.log(obj_class, text, ex, LogLevel::ERROR) 110 | end 111 | 112 | rescue CanNotLogException 113 | puts "********************************************************" 114 | puts "Directories is created again!" 115 | init_app 116 | puts "Create is done!" 117 | puts "********************************************************" 118 | end 119 | 120 | ### 121 | # FATAL 122 | # 123 | ### 124 | def fatal_logger(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 125 | if @config.loglevel.value <= LogLevel::FATAL.value 126 | # :TODO 127 | @appender.log(obj_class, text, ex, LogLevel::FATAL) 128 | end 129 | 130 | rescue CanNotLogException 131 | puts "********************************************************" 132 | puts "Directories is created again!" 133 | init_app 134 | puts "Create is done!" 135 | puts "********************************************************" 136 | end 137 | end 138 | end 139 | end 140 | -------------------------------------------------------------------------------- /src/katip/core/appender.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | module Core 3 | class Appender 4 | def initialize(@config : Config) 5 | @json_init_info = "{\"katip\":\"#{VERSION}\",\"info\":{\"description\":\"#{@config.info.description}\",\"project\":\"#{@config.info.project}\",\"version\":\"#{@config.info.version}\"},\"errors\":[" 6 | end 7 | 8 | def log(obj_class : Object.class, text : String, ex : Exception, loglevel : LogLevel) 9 | if @config.logclassification.value == LogClassification::DATE_DAY.value 10 | Core::Engine.add_error_log_json("#{@config.path}/#{Time.local.year}-#{Time.local.month}-#{Time.local.day}.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 11 | elsif @config.logclassification.value == LogClassification::DATE_MINUTES.value 12 | Core::Engine.add_error_log_json("#{@config.path}/#{Time.local.year}-#{Time.local.month}-#{Time.local.day}|#{Time.local.hour}:#{Time.local.minute}.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 13 | elsif @config.logclassification.value == LogClassification::DATE_HOUR.value 14 | Core::Engine.add_error_log_json("#{@config.path}/#{Time.local.year}-#{Time.local.month}-#{Time.local.day}|#{Time.local.hour}:00.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 15 | elsif @config.logclassification.value == LogClassification::DATE_MONTH.value 16 | Core::Engine.add_error_log_json("#{@config.path}/#{Time.local.year}-#{Time.local.month}-01.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 17 | elsif @config.logclassification.value == LogClassification::LOGLEVEL.value 18 | Core::Engine.add_error_log_json("#{@config.path}/#{loglevel}.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 19 | elsif @config.logclassification.value == LogClassification::EXCEPTION.value 20 | Core::Engine.add_error_log_json("#{@config.path}/#{ex.class}.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 21 | elsif @config.logclassification.value == LogClassification::CLASS.value 22 | Core::Engine.add_error_log_json("#{@config.path}/#{obj_class}.json", @json_init_info, Core::Engine.create_log_json(obj_class, text, ex, loglevel)) 23 | end 24 | 25 | rescue CanNotLogException 26 | raise CanNotLogException.new 27 | rescue Exception 28 | puts "********************************************************" 29 | puts "I am finding unknown Exception! Please create issue on https://github.com/guvencenanguvenal/katip/issues" 30 | puts "********************************************************" 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /src/katip/core/engine.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | module Core 3 | class Engine 4 | def self.add_error_log_json(filename : String, json_init_info : String, json : String) 5 | if !File.file?(filename) 6 | File.open(filename, "w+") do |file| 7 | file.print(json_init_info + json + "]}") 8 | end 9 | else 10 | File.open(filename, "r+") do |file| 11 | file.seek(-2, IO::Seek::End) 12 | file.print("," + json + "]}") 13 | end 14 | end 15 | 16 | rescue 17 | puts "********************************************************" 18 | puts "Error! I can not create your log file!" 19 | puts "Please control your path!" 20 | puts "--- Another trick;" 21 | puts "Log file may already open or may use anoter program!" 22 | puts "********************************************************" 23 | raise CanNotLogException.new 24 | end 25 | 26 | def self.create_log_json(obj_class : Object.class, text : String, ex : Exception, loglevel : LogLevel) : String 27 | _log_level = "" 28 | 29 | case loglevel.value 30 | when LogLevel::ALL.value 31 | _log_level = "ALL" 32 | when LogLevel::DEBUG.value 33 | _log_level = "DEBUG" 34 | when LogLevel::INFO.value 35 | _log_level = "INFO" 36 | when LogLevel::WARN.value 37 | _log_level = "WARN" 38 | when LogLevel::ERROR.value 39 | _log_level = "ERROR" 40 | when LogLevel::FATAL.value 41 | _log_level = "FATAL" 42 | end 43 | 44 | "{\"date\":\"#{Time.local}\", \"class\":\"#{obj_class}\", \"message\":\"#{text}\", \"exception_type\":\"#{ex.class}\", \"exception_message\":\"#{ex.message}\", \"log_level\":\"#{_log_level}\"}" 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /src/katip/core/enums.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | enum LogLevel 3 | ALL 4 | DEBUG 5 | INFO 6 | WARN 7 | ERROR 8 | FATAL 9 | OFF 10 | end 11 | 12 | enum LogClassification 13 | DATE_MINUTES 14 | DATE_HOUR 15 | DATE_DAY 16 | DATE_WEEK 17 | DATE_MONTH 18 | LOGLEVEL 19 | EXCEPTION 20 | CLASS 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /src/katip/exceptions/CanNotLogException.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | class CanNotLogException < Exception 3 | 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/katip/exceptions/NotSetException.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | class NotSetException < Exception 3 | 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/katip/info.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | class Information 3 | property description = "" 4 | property project = "" 5 | property version = "" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/katip/logger.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | class Logger 3 | property config : Config 4 | 5 | def initialize 6 | @config = Config.new 7 | @app = Core::App.new(@config) 8 | end 9 | 10 | def configure 11 | yield @config 12 | @app.configure @config 13 | 14 | self 15 | end 16 | 17 | ### 18 | # 19 | # 20 | ### 21 | def debug(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 22 | @app.debug_logger(text, obj_class, ex) 23 | end 24 | 25 | ### 26 | # 27 | # 28 | ### 29 | def info(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 30 | @app.info_logger(text, obj_class, ex) 31 | end 32 | 33 | ### 34 | # 35 | # 36 | ### 37 | def warn(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 38 | @app.warn_logger(text, obj_class, ex) 39 | end 40 | 41 | ### 42 | # 43 | # 44 | ### 45 | def error(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 46 | @app.error_logger(text, obj_class, ex) 47 | end 48 | 49 | ### 50 | # 51 | # 52 | ### 53 | def fatal(text : String, obj_class = Object.class, ex = NotSetException.new("Not Init")) 54 | @app.fatal_logger(text, obj_class, ex) 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /src/katip/version.cr: -------------------------------------------------------------------------------- 1 | module Katip 2 | VERSION = "0.1.0" 3 | end 4 | --------------------------------------------------------------------------------