cli_application 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4b0f3ceada563c7810adb8fb2ec62d225ba1ff2
4
- data.tar.gz: 77c131b002d7f03b7cb64b2106e4cc13f88970f6
3
+ metadata.gz: 97e161aaae872e64c8eb70ae91392d210c789564
4
+ data.tar.gz: c5d7d088bedf9edb2b02eaa0348d0d2da3a272cd
5
5
  SHA512:
6
- metadata.gz: 3744fa04ba99818fec0cc888ebe108fcfcb3481e8546e7e8bd4b9d2d7f21c3ec4dbcde92d624dc255d567331539e4aef8f10e955ddd5d25a0cda7bd3a416de32
7
- data.tar.gz: 3c144c21e11e0cf74b4bc2f4c222e1b4763d9471d00a3b7090d0c25219e5fa3810ba45ee85fd09ddcac8d7e5e3a62f8e7a6cc23c2eab778c11f9b9682849d11b
6
+ metadata.gz: 55ae149543d5269befed662bb517dc4caf9137d45f9d0bb9afa345a7093fba129a8cdf9afb6134c499920fe90d92955afe990bf452eb399de8f5315e8b390ea6
7
+ data.tar.gz: bb55fb421ad8fc54f29db17678b788332151b7a37115c097be66063025b908e518318efab920ed87b363a8f969d87b37a57702972573f2c2df24e0cd8d38c204
@@ -24,6 +24,13 @@ module CliApplication # :nodoc:
24
24
  require 'cli_application/mail_lib/sendmail'
25
25
  require 'cli_application/mail_lib/log'
26
26
 
27
+ # Функции записи логов в файл или в базу данных
28
+ require 'cli_application/log/base'
29
+ require 'cli_application/log/file'
30
+ require 'cli_application/log/database'
31
+ require 'cli_application/log/config'
32
+ require 'cli_application/log/none'
33
+
27
34
  require 'cli_application/json_struct'
28
35
  require 'cli_application/config'
29
36
  require 'cli_application/databases'
@@ -35,7 +35,13 @@ module CliApplication
35
35
  # @param [String] classfolder директория, в которой расположен базовый класс проекта
36
36
  # @param [Sym] lang язык работы приложения (реализовано не полностью)
37
37
  def initialize(argv, appfolder, classfolder, lang = :ru)
38
+ # ru: Настраиваем локализацию приложения
39
+ # en: setup a localization
38
40
  StTools.configure { |config| config.locale = lang }
41
+ I18n.load_path += Dir[File.join(__dir__, 'locales', '*.{rb,yml}')]
42
+ I18n.available_locales = [:ru]
43
+ I18n.default_locale = lang
44
+ I18n.backend.load_translations
39
45
 
40
46
  @folders = Hash.new
41
47
  @folders[:app] = appfolder
@@ -50,9 +56,23 @@ module CliApplication
50
56
 
51
57
  @footer = nil
52
58
 
59
+ init_app_log
53
60
  init_app
54
61
  end
55
62
 
63
+ def init_app_log
64
+ log_config = ::CliApplication::Log::Config.new(@config)
65
+ case log_config.type
66
+ when :none
67
+ @cli_log = ::CliApplication::Log::None.new
68
+ when :file
69
+ @cli_log = ::CliApplication::Log::File.new(self, log_config, @folders[:class])
70
+ else
71
+ raise I18n.t('error.config.log_unknown', type: log_config.type.to_s.inspect)
72
+ end
73
+ @cli_log.save_app_start_information
74
+ end
75
+
56
76
  #-------------------------------------------------------------
57
77
  #
58
78
  # Функции для использования внутри функции main
@@ -223,8 +243,16 @@ module CliApplication
223
243
 
224
244
  # При вызове данного метода начнется выполнение кода приложения (будет осуществен вызов функции main)
225
245
  def run
226
- self.exitcode = main || 255
227
- self.executed_at = (::Time.now - @started_at).to_f
246
+ @cli_log.save_app_run_information
247
+ begin
248
+ self.exitcode = main || 255
249
+ rescue Exception => e
250
+ @cli_log.set_exception(e)
251
+ raise e
252
+ ensure
253
+ self.executed_at = (::Time.now - @started_at).to_f
254
+ @cli_log.save_app_finish_information
255
+ end
228
256
  puts_footer
229
257
  @cli_stat_record.save
230
258
  self.exitcode
@@ -10,6 +10,7 @@
10
10
  module CliApplication
11
11
  class Config < OpenStruct
12
12
  attr_reader :config
13
+ attr_reader :filename
13
14
 
14
15
  # Конструктор. Вызывается при создании класса приложения. Данный класс доступен
15
16
  # в главной функции приложения (main) через переменную config
@@ -21,6 +22,7 @@ module CliApplication
21
22
  @folders = folders
22
23
  @filenames = Array.new
23
24
  @config_filename = File.join([folders[:class], 'config.yml'])
25
+ @filename = @config_filename
24
26
  load_config(@config_filename)
25
27
  end
26
28
 
@@ -0,0 +1,20 @@
1
+ ru:
2
+ error:
3
+ config:
4
+ log_section_missing: "В конфигурационном файле %{filename} отсутствует секция \"log\""
5
+ log_section_type_wrong: "Секция \"log\" конфигурационого файла %{filename} должна принимать одно из следующих значений: none, file, database (указано значение %{type})"
6
+ log_unknown: "Неизвестный тип логгирования: %{type}"
7
+ log_section_overwrite: "Необходимо переписать функцию \"%{func}\" в дочернем классе"
8
+
9
+ config:
10
+ log_section:
11
+ start_header: "-- Запуск приложения ---------------------------"
12
+ run_header: "-- Пользовательская секция ---------------------"
13
+ finish_header: "-- Завершение приложения -----------------------"
14
+ app_name: "Приложение: %{name}"
15
+ app_started_at: "Приложение запущено: %{time}"
16
+ app_executed_at: "Приложение завершено: %{time} (время выполнения: %{executed_at} сек.)"
17
+ app_exitcode: "Результат завершения: %{exitcode} (%{status})"
18
+ app_memory: "Использование памяти: %{value}"
19
+ app_script_name: "Имя скрипта: %{name}"
20
+
@@ -0,0 +1,57 @@
1
+ # module CliApplication::Log
2
+
3
+ В ходе эксплуатации библиотеки мне пришлось столкнуться с некоторыми проблемами, которые не сразу были
4
+ диагностированы. Например, в ходе выполнения скрипта, через полгода, случайно выяснялось, что скрипт
5
+ последний месяц работал с ошибкой. Подобных ситуаций может быть две:
6
+
7
+ - Cкрипт был отлажен под девелоперским профилем, записаны логи, затем скрипт помещен в cron. После этого,
8
+ при запуске из под крона, возникала ошибка записи лога (из-под крона другие права), которая не выводилась
9
+ в консоль. Как следствие - под кроном скрипт не работет, а причина неизвестна.
10
+ - В ходе исполнения скрипта возникали не предусмотренные на этапе отладки исключительные ситуации, и скрипт
11
+ прекращал работать. Если не озаботиться выводом диагностических сообщений, например, в почту, то об этой
12
+ ситуации можно было долго не узнать.
13
+
14
+ Поэтому в CliApplication добавляются функции логгирования работы приложения. Практика показывет, что полные
15
+ логи никто не изучает (трудоемко), поэтому логгирование осуществляется только для последнего запуска скрипта.
16
+
17
+ При этом, функции логгирования делают следующее:
18
+ 1. Уже на этапе девелопмента предупреждают о ситуации, если запись лог-файлов будет ограничена по причине прав.
19
+ Это дает гарантию того, что при запуске из под крона данные будут гарантированно записываться в файл.
20
+ 2. Записывают информацию о старте приложения. Если есть блок старта приложения, и ничего больше - где-то
21
+ произошел "вылет" приложения.
22
+ 3. Дает возможность записи пользовательских сообщений (например, для отладки или контроля исполнения)
23
+ 4. Пишет финальную часть - время исполнения, результат, занятую память.
24
+
25
+ Помимо файла, запись также возможна в базу данных, что дает возможность удаленно мониторить исполнение
26
+ скриптов
27
+
28
+ ## Настройка логгирования
29
+
30
+ Для настройки логгирования необходимо создать секцию cli/log в конфигурационном файле. Формат секции
31
+ определяется значением type. Например:
32
+
33
+ ```yaml
34
+ cli:
35
+ log:
36
+ type: none
37
+ ```
38
+
39
+ ```yaml
40
+ cli:
41
+ log:
42
+ type: file
43
+ location: <folder>
44
+ ```
45
+
46
+ ```yaml
47
+ cli:
48
+ log:
49
+ type: database
50
+ database: <имя секции cli/database>
51
+ ```
52
+
53
+ ## Логгирование в файл
54
+
55
+
56
+ ## Логгирование в базу данных
57
+
@@ -0,0 +1,27 @@
1
+ module CliApplication
2
+ module Log
3
+ class Base
4
+
5
+ def log(message)
6
+ raise I18n.t('error.config.log_section_overwrite', func: 'log')
7
+ end
8
+
9
+ def save_app_start_information
10
+ raise I18n.t('error.config.log_section_overwrite', func: 'save_app_start_information')
11
+ end
12
+
13
+ def save_app_run_information
14
+ raise I18n.t('error.config.log_section_overwrite', func: 'save_app_run_information')
15
+ end
16
+
17
+ def save_app_finish_information
18
+ raise I18n.t('error.config.log_section_overwrite', func: 'save_app_finish_information')
19
+ end
20
+
21
+ def set_exception(e)
22
+ @exception = e
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,71 @@
1
+ module CliApplication
2
+ module Log
3
+ class Config
4
+ attr_reader :log_section
5
+ attr_reader :type
6
+
7
+ # Конструктор. Вызывается при создании класса приложения. В Конструктор передается
8
+ # секция конфигурационного файла, описывающего правила логгирования приложения
9
+ # Форматы файла:
10
+ #
11
+ # Логгирование отключено (не рекомендуется)
12
+ # cli:
13
+ # log:
14
+ # type: none
15
+ #
16
+ # Логгирование в файл
17
+ # cli:
18
+ # log:
19
+ # type: file
20
+ # location: папка для храннения логов
21
+ #
22
+ # Логгирование в базу данных
23
+ # cli:
24
+ # log:
25
+ # type: database
26
+ # database: имя конфигурации базы данных
27
+ # table_name: имя таблицы. По умолчанию - st_cli_application_log
28
+ #
29
+ #
30
+ # 1. Описание хранения логов в файлах
31
+ # Если ключ location не указан, то в качестве базовой папки будет использована
32
+ # папка класса, с добавлением logs. Если папки нет - она будет создана.
33
+ # Имя файла лога - соответствует имени скрипта, с добавкой '/logs/'
34
+ # При запуске осуществляется проверка прав на указанные файлы. Если есть риск незапуска
35
+ # скрипта под другими пользователями - то будет исключение.
36
+ # Файл создается в два этапа. Первый - создается файл при запуске, с указанием даты старта
37
+ # В случае ошибки - она пишется в лог. В случае успешного завершения - запись об этом тоже пишется
38
+ # в лог
39
+ #
40
+ # 2. Описание хранения логов в базе данных
41
+ #
42
+ def initialize(config)
43
+ @possible_keys = [:none, :file, :database]
44
+
45
+ @log_section = config.cli.log
46
+ @config = config
47
+ check_section_exist
48
+ check_section_type
49
+ end
50
+
51
+
52
+ private
53
+
54
+
55
+ def check_section_type
56
+ @type = @log_section.type.downcase.to_sym rescue :unknown
57
+ unless @possible_keys.include?(@type)
58
+ raise I18n.t('error.config.log_section_type_wrong', filename: @config.filename, type: @type.to_s.inspect)
59
+ end
60
+ end
61
+
62
+ def check_section_exist
63
+ if @log_section.nil?
64
+ raise I18n.t('error.config.log_section_missing', filename: @config.filename)
65
+ end
66
+ end
67
+
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,21 @@
1
+ module CliApplication
2
+ module Log
3
+ class Database < CliApplication::Log::Base
4
+
5
+ def initialize(table)
6
+ super
7
+ @table = table
8
+ end
9
+
10
+ def log_possible?
11
+
12
+ end
13
+
14
+ def save
15
+
16
+ end
17
+
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,96 @@
1
+ module CliApplication
2
+ module Log
3
+ class File < CliApplication::Log::Base
4
+ attr_reader :folder
5
+ attr_reader :filename
6
+
7
+ def initialize(app, log, class_folder)
8
+ @app = app
9
+ @log = log
10
+ @class_folder = class_folder
11
+ init_log
12
+ end
13
+
14
+ def save_app_start_information
15
+ log(I18n.t('config.log_section.start_header'))
16
+ log(I18n.t('config.log_section.app_name', name: $PROGRAM_NAME))
17
+ log(I18n.t('config.log_section.app_script_name', name: ::File.basename($PROGRAM_NAME)))
18
+ log(I18n.t('config.log_section.app_started_at', time: Time.zone.now))
19
+ log("")
20
+ end
21
+
22
+ def save_app_run_information
23
+ log(I18n.t('config.log_section.run_header'))
24
+ log("")
25
+ end
26
+
27
+ def save_app_finish_information
28
+ log(I18n.t('config.log_section.finish_header'))
29
+ unless @exception.nil?
30
+ log(@exception.message)
31
+ log(@exception.backtrace.join("\n"))
32
+ end
33
+ log(I18n.t('config.log_section.app_executed_at', time: Time.zone.now, executed_at: @app.executed_at.round(3)))
34
+ log(I18n.t('config.log_section.app_memory', value: StTools::Human.memory))
35
+ log(I18n.t('config.log_section.app_exitcode', exitcode: @app.exitcode, status: ((@app.exitcode == 0 ? 'SUCCESS' : 'FAIL'))))
36
+ end
37
+
38
+ def log(message)
39
+ ::File.open(@filename, 'a') {|f| f.write message + "\n" }
40
+ ::File.chmod(0777, @filename)
41
+ end
42
+
43
+
44
+ private
45
+
46
+
47
+ def init_log
48
+ init_names
49
+ create_folder
50
+ check_folder_and_file
51
+ end
52
+
53
+ # Проверка на доступность папки и файла. Если с этим проблема,
54
+ # то выбрасываем исключение, чтобы уже на этапе отладки было понятно, что
55
+ # при запуске приложения из под cron будут проблемы
56
+ def check_folder_and_file
57
+ if ::File.exists?(@filename)
58
+ delete_file
59
+ else
60
+ check_folder
61
+ end
62
+ end
63
+
64
+ # Проверка на возможность дописывать в вфайл из под любого пользователя
65
+ # Если права не XXX, то выбрасываем исключение
66
+ def delete_file
67
+ ::File.delete(@filename)
68
+ end
69
+
70
+ def check_folder
71
+ if Dir.exists?(@folder)
72
+ # s = Dir.stat(@filename)
73
+ # puts "Dir >>>>>>>>>>>>>>>>>> #{s.mode}"
74
+ end
75
+ end
76
+
77
+ def create_folder
78
+ unless Dir.exists?(@folder)
79
+ Dir.mkdir(@folder, 0777)
80
+ end
81
+ end
82
+
83
+ def init_names
84
+ if @log.log_section.location.nil?
85
+ # Локация не задана
86
+ @folder = ::File.join(@class_folder, 'logs')
87
+ else
88
+ # Локация в конфиге задана
89
+ @folder = @log.log_section.location
90
+ end
91
+ @filename = ::File.join(@folder, ::File.basename($PROGRAM_NAME, '.rb')+'.log')
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,19 @@
1
+ module CliApplication
2
+ module Log
3
+ class None < CliApplication::Log::Base
4
+
5
+ def log(message)
6
+ end
7
+
8
+ def save_app_start_information
9
+ end
10
+
11
+ def save_app_run_information
12
+ end
13
+
14
+ def save_app_finish_information
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -1,19 +1,21 @@
1
1
  module CliApplication
2
- class Stat # :nodoc:
2
+ class Stat # :nodoc:
3
3
  attr_reader :stat
4
4
 
5
+
5
6
  def initialize(folders)
6
7
  @stat_filename = File.join([folders[:class], 'stat', ::StTools::System.exename.gsub(/\.rb$/, '.yml')])
7
- @stat_folder = File.join([folders[:class], 'stat'])
8
+ @stat_folder = File.join([folders[:class], 'stat'])
8
9
  create_folder
9
10
 
10
11
  init_stat
11
- folders[:stat] = @stat_folder
12
+ folders[:stat] = @stat_folder
12
13
  @stat[:folders] = folders
13
14
 
14
15
  @prev = load_stat
15
16
  end
16
17
 
18
+
17
19
  #-------------------------------------------------------------
18
20
  #
19
21
  # Функции настройки приложения
@@ -23,36 +25,38 @@ module CliApplication
23
25
  @stat[:last][:exitcode] = code
24
26
  end
25
27
 
28
+
26
29
  def executed_at=(at)
27
30
  @stat[:last][:executed_at] = at
28
31
  end
29
32
 
33
+
30
34
  def last_started_at=(at)
31
35
  @stat[:last][:started_at] = at.to_s
32
- @stat[:last_started_at] = at.to_s
36
+ @stat[:last_started_at] = at.to_s
33
37
  end
34
38
 
39
+
35
40
  def version=(val)
36
41
  @stat[:version] = val
37
42
  end
38
43
 
44
+
39
45
  def description=(val)
40
46
  @stat[:description] = val
41
47
  end
42
48
 
49
+
43
50
  def shortdescription=(val)
44
51
  @stat[:shortdescription] = val
45
52
  end
46
53
 
54
+
47
55
  def releasedate=(val)
48
56
  @stat[:releasedate] = val
49
57
  end
50
58
 
51
59
 
52
-
53
-
54
-
55
-
56
60
  def last_started_at_human
57
61
  res = last_started_at
58
62
  if res.nil? || res == ''
@@ -62,45 +66,62 @@ module CliApplication
62
66
  end
63
67
  end
64
68
 
69
+
65
70
  def startes_human
66
71
  res = @prev[:avg][:starts]
67
72
  "Всего было #{res} запусков"
68
73
  end
69
74
 
75
+
70
76
  def last_started_at
71
77
  @prev[:last][:started_at] || ::Time.zone.now
72
78
  end
73
79
 
80
+
74
81
  def load_stat
75
- YAML.load_file(@stat_filename)
82
+ res = YAML.load_file(@stat_filename, {})
83
+ res.empty? ? Marshal.load(Marshal.dump(init_stat)) : res
76
84
  rescue
77
- Marshal.load( Marshal.dump(init_stat))
85
+ Marshal.load(Marshal.dump(init_stat))
78
86
  end
79
87
 
88
+
80
89
  def save
81
90
  @prev = load_stat
82
91
  update_stat
83
- File.open(@stat_filename, 'w') {|f| f.write @prev.to_yaml }
92
+ File.open(@stat_filename, 'w') { |f| f.write @prev.to_yaml }
84
93
  end
85
94
 
95
+
86
96
  def create_folder
87
97
  unless Dir.exist?(@stat_folder)
88
98
  Dir.mkdir(@stat_folder, 0777)
89
99
  end
100
+
101
+ # ToDo убрать в модуль Log
102
+ # 2018-01-06, добавляем проверку на доступность папки и файла. Если с этим проблема,
103
+ # то выбрасываем исключение, чтобы уже на этапе отладки было понятно, что
104
+ # при запуске приложения из под cron будут проблемы
105
+ if File.exist?(@stat_filename)
106
+ s = File.stat(@stat_filename)
107
+ puts ">>>>>>>>>>>>>>>>>> #{s.mode}"
108
+ end
90
109
  end
91
110
 
111
+
92
112
  def timezone=(val)
93
113
  @stat[:timezone] = val
94
114
  end
95
115
 
116
+
96
117
  def update_stat
97
- @prev[:name] = @stat[:name]
118
+ @prev[:name] = @stat[:name]
98
119
  @prev[:shortdescription] = @stat[:shortdescription]
99
- @prev[:version] = @stat[:version]
100
- @prev[:releasedate] = @stat[:releasedate]
101
- @prev[:timezone] = ::Time.zone.name
102
- @prev[:last_started_at] = @stat[:last_started_at]
103
- @prev[:folders] = @stat[:folders]
120
+ @prev[:version] = @stat[:version]
121
+ @prev[:releasedate] = @stat[:releasedate]
122
+ @prev[:timezone] = ::Time.zone.name
123
+ @prev[:last_started_at] = @stat[:last_started_at]
124
+ @prev[:folders] = @stat[:folders]
104
125
 
105
126
  make_averages(@prev[:avg])
106
127
  make_last(@prev[:last])
@@ -112,58 +133,61 @@ module CliApplication
112
133
  tmp << @prev[:last][:memory]
113
134
 
114
135
  @prev[:last10].unshift(tmp.join(','))
115
- @prev[:last10] = @prev[:last10][0,10]
136
+ @prev[:last10] = @prev[:last10][0, 10]
116
137
  end
117
138
 
139
+
118
140
  def init_stat
119
- @stat = Hash.new
120
- @stat[:name] = ::StTools::System.exename
141
+ @stat = Hash.new
142
+ @stat[:name] = ::StTools::System.exename
121
143
  @stat[:shortdescription] = ''
122
- @stat[:version] = ''
123
- @stat[:releasedate] = ''
124
- @stat[:timezone] = ''
125
- @stat[:last_started_at] = ''
126
- @stat[:folders] = @folders
127
-
128
- @stat[:avg] = Hash.new
129
- @stat[:avg][:starts] = 0
130
- @stat[:avg][:executed_at] = 0
144
+ @stat[:version] = ''
145
+ @stat[:releasedate] = ''
146
+ @stat[:timezone] = ''
147
+ @stat[:last_started_at] = ''
148
+ @stat[:folders] = @folders
149
+
150
+ @stat[:avg] = Hash.new
151
+ @stat[:avg][:starts] = 0
152
+ @stat[:avg][:executed_at] = 0
131
153
  @stat[:avg][:executed_at_human] = ''
132
- @stat[:avg][:memory] = 0
154
+ @stat[:avg][:memory] = 0
133
155
 
134
- @stat[:last] = Hash.new
135
- @stat[:last][:started_at] = nil
136
- @stat[:last][:executed_at] = 0
156
+ @stat[:last] = Hash.new
157
+ @stat[:last][:started_at] = nil
158
+ @stat[:last][:executed_at] = 0
137
159
  @stat[:last][:executed_at_human] = ''
138
- @stat[:last][:memory] = ''
139
- @stat[:last][:exitcode] = 0
160
+ @stat[:last][:memory] = ''
161
+ @stat[:last][:exitcode] = 0
140
162
 
141
163
  @stat[:last10] = Array.new
142
164
 
143
165
  @stat
144
166
  end
145
167
 
168
+
146
169
  def make_averages(avg)
147
170
  if avg[:starts] == 0
148
- avg[:starts] = 1
149
- avg[:executed_at] = @stat[:last][:executed_at]
171
+ avg[:starts] = 1
172
+ avg[:executed_at] = @stat[:last][:executed_at]
150
173
  avg[:executed_at_human] = ::StTools::Human.ago_in_words_pair(avg[:executed_at].to_i).join(' ')
151
- avg[:memory] = ::StTools::System.memory.to_i
174
+ avg[:memory] = ::StTools::System.memory.to_i
152
175
  else
153
- mul = avg[:starts]
154
- avg[:starts] += 1
155
- avg[:executed_at] = ((avg[:executed_at]*mul + @stat[:last][:executed_at]).to_f / avg[:starts]).round(6)
176
+ mul = avg[:starts]
177
+ avg[:starts] += 1
178
+ avg[:executed_at] = ((avg[:executed_at] * mul + @stat[:last][:executed_at]).to_f / avg[:starts]).round(6)
156
179
  avg[:executed_at_human] = ::StTools::Human.ago_in_words_pair(avg[:executed_at]).join(' ')
157
- avg[:memory] = (avg[:memory]*mul + ::StTools::System.memory).to_i / avg[:starts]
180
+ avg[:memory] = (avg[:memory] * mul + ::StTools::System.memory).to_i / avg[:starts]
158
181
  end
159
182
  end
160
183
 
184
+
161
185
  def make_last(last)
162
- last[:started_at] = @stat[:last_started_at]
163
- last[:executed_at] = @stat[:last][:executed_at]
186
+ last[:started_at] = @stat[:last_started_at]
187
+ last[:executed_at] = @stat[:last][:executed_at]
164
188
  last[:executed_at_human] = ::StTools::Human.ago_in_words_pair(last[:executed_at]).join(' ')
165
- last[:memory] = ::StTools::Human.memory
166
- last[:exitcode] = @stat[:last][:exitcode]
189
+ last[:memory] = ::StTools::Human.memory
190
+ last[:exitcode] = @stat[:last][:exitcode]
167
191
  end
168
192
 
169
193
  end
@@ -1,3 +1,3 @@
1
1
  module CliApplication
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.10"
3
3
  end
@@ -1,33 +1,21 @@
1
1
  ---
2
2
  :name: app.rb
3
- :shortdescription: "Пример 2 - Настройки CLI-приложения"
4
- :version: '1.0'
5
- :releasedate: '2015-05-11'
3
+ :shortdescription: ''
4
+ :version: ''
5
+ :releasedate: ''
6
6
  :timezone: Moscow
7
- :last_started_at: '2017-01-04 12:18:36 +0300'
8
- :folders:
9
- :app: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/examples/2"
10
- :class: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/examples/1"
11
- :stat: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/examples/1/stat"
7
+ :last_started_at: ''
8
+ :folders:
12
9
  :avg:
13
- :starts: 244
14
- :executed_at: 4.383912
15
- :executed_at_human: 4.383912 секунд
16
- :memory: 391427
10
+ :starts: 1
11
+ :executed_at: 0
12
+ :executed_at_human: 0 секунд
13
+ :memory: 44269568
17
14
  :last:
18
- :started_at: '2017-01-04 12:18:36 +0300'
19
- :executed_at: 0.059596
20
- :executed_at_human: 0.059596 секунд
21
- :memory: 41.8 Мбайт
22
- :exitcode: 255
15
+ :started_at: ''
16
+ :executed_at: 0
17
+ :executed_at_human: 0 секунд
18
+ :memory: 42.2 Мбайт
19
+ :exitcode: 0
23
20
  :last10:
24
- - 2017-01-04 12:18:36 +0300,255,0.059596,41.8 Мбайт
25
- - 2017-01-04 12:18:26 +0300,255,0.053526,41.2 Мбайт
26
- - 2015-11-12 08:04:04 +0300,10,0.032581,35 кбайт
27
- - 2015-10-26 22:16:55 +0300,0,0.029927,36 кбайт
28
- - 2015-10-26 22:16:01 +0300,0,0.02892,36 кбайт
29
- - 2015-10-26 22:10:40 +0300,0,0.033229,36 кбайт
30
- - 2015-10-26 22:10:25 +0300,0,0.036708,36 кбайт
31
- - 2015-10-26 22:08:56 +0300,0,0.036485,38 кбайт
32
- - 2015-10-26 22:07:56 +0300,0,0.035323,36 кбайт
33
- - 2015-10-26 22:04:20 +0300,255,0.053609,35 кбайт
21
+ - ",0,0,42.2 Мбайт"
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: utf-8
3
+ require './cli_example.rb'
4
+
5
+ class TestApp < CliExample
6
+
7
+ def main
8
+ puts "Hello, world!"
9
+ end
10
+
11
+ end
12
+
13
+ app = TestApp.new(ARGV, __dir__)
14
+
15
+ app.version = '1.0'
16
+ app.releasedate = '2018-01-06'
17
+ app.shortdescription = 'Тестовый скрипт демонстрации CliApplication'
18
+ app.description = "CliApplication gem демо. #{app.shortdescription}"
19
+
20
+ app.help
21
+
22
+ app.run
23
+ exit(app.exitcode)
24
+
@@ -0,0 +1,14 @@
1
+ require '../../../lib/cli_application.rb'
2
+
3
+ class CliExample < CliApplication::App
4
+
5
+ def initialize(argv, folder, lang = :ru)
6
+ super(argv, folder, __dir__, lang)
7
+ end
8
+
9
+ def init_app
10
+ super
11
+ add_config('config.yml', :class)
12
+ end
13
+
14
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: utf-8
3
+ require './cli_example.rb'
4
+
5
+ class TestApp < CliExample
6
+
7
+ def main
8
+ puts "Hello, world!"
9
+ end
10
+
11
+ end
12
+
13
+ app = TestApp.new(ARGV, __dir__)
14
+
15
+ app.version = '1.0'
16
+ app.releasedate = '2018-01-06'
17
+ app.shortdescription = 'Тестовый скрипт демонстрации CliApplication'
18
+ app.description = "CliApplication gem демо. #{app.shortdescription}"
19
+
20
+ app.help
21
+
22
+ app.run
23
+ exit(app.exitcode)
24
+
@@ -0,0 +1,14 @@
1
+ require '../../../lib/cli_application.rb'
2
+
3
+ class CliExample < CliApplication::App
4
+
5
+ def initialize(argv, folder, lang = :ru)
6
+ super(argv, folder, __dir__, lang)
7
+ end
8
+
9
+ def init_app
10
+ super
11
+ add_config('config.yml', :class)
12
+ end
13
+
14
+ end
@@ -0,0 +1,21 @@
1
+ ---
2
+ :name: app.rb
3
+ :shortdescription: ''
4
+ :version: ''
5
+ :releasedate: ''
6
+ :timezone: Moscow
7
+ :last_started_at: ''
8
+ :folders:
9
+ :avg:
10
+ :starts: 1
11
+ :executed_at: 0
12
+ :executed_at_human: 0 секунд
13
+ :memory: 41975808
14
+ :last:
15
+ :started_at: ''
16
+ :executed_at: 0
17
+ :executed_at_human: 0 секунд
18
+ :memory: 40.0 Мбайт
19
+ :exitcode: 0
20
+ :last10:
21
+ - ",0,0,40.0 Мбайт"
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: utf-8
3
+ require './cli_example.rb'
4
+
5
+ class TestApp < CliExample
6
+
7
+ def main
8
+ puts "Hello, world!"
9
+ end
10
+
11
+ end
12
+
13
+ app = TestApp.new(ARGV, __dir__)
14
+
15
+ app.version = '1.0'
16
+ app.releasedate = '2018-01-06'
17
+ app.shortdescription = 'Тестовый скрипт демонстрации CliApplication'
18
+ app.description = "CliApplication gem демо. #{app.shortdescription}"
19
+
20
+ app.help
21
+
22
+ app.run
23
+ exit(app.exitcode)
24
+
@@ -0,0 +1,14 @@
1
+ require '../../../lib/cli_application.rb'
2
+
3
+ class CliExample < CliApplication::App
4
+
5
+ def initialize(argv, folder, lang = :ru)
6
+ super(argv, folder, __dir__, lang)
7
+ end
8
+
9
+ def init_app
10
+ super
11
+ add_config('config.yml', :class)
12
+ end
13
+
14
+ end
@@ -0,0 +1,26 @@
1
+ ---
2
+ :name: app.rb
3
+ :shortdescription: "Тестовый скрипт демонстрации CliApplication"
4
+ :version: '1.0'
5
+ :releasedate: '2018-01-06'
6
+ :timezone: Moscow
7
+ :last_started_at: '2018-01-06 23:26:28 +0300'
8
+ :folders:
9
+ :app: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/log/03_log_section_type_none_ok"
10
+ :class: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/log/03_log_section_type_none_ok"
11
+ :stat: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/log/03_log_section_type_none_ok/stat"
12
+ :avg:
13
+ :starts: 3
14
+ :executed_at: 0.040108
15
+ :executed_at_human: 0.040108 секунд
16
+ :memory: 41891157
17
+ :last:
18
+ :started_at: '2018-01-06 23:26:28 +0300'
19
+ :executed_at: 0.054604
20
+ :executed_at_human: 0.054604 секунд
21
+ :memory: 40.1 Мбайт
22
+ :exitcode: 255
23
+ :last10:
24
+ - 2018-01-06 23:26:28 +0300,255,0.054604,40.1 Мбайт
25
+ - 2018-01-06 20:20:48 +0300,255,0.06572,39.7 Мбайт
26
+ - ",0,0,40.0 Мбайт"
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: utf-8
3
+ require './cli_example.rb'
4
+
5
+ class TestApp < CliExample
6
+
7
+ def main
8
+ puts "Hello, world!"
9
+ 0
10
+ end
11
+
12
+ end
13
+
14
+ app = TestApp.new(ARGV, __dir__)
15
+
16
+ app.version = '1.0'
17
+ app.releasedate = '2018-01-06'
18
+ app.shortdescription = 'Тестовый скрипт демонстрации CliApplication'
19
+ app.description = "CliApplication gem демо. #{app.shortdescription}"
20
+
21
+ app.help
22
+
23
+ app.run
24
+ exit(app.exitcode)
25
+
@@ -0,0 +1,14 @@
1
+ require '../../../lib/cli_application.rb'
2
+
3
+ class CliExample < CliApplication::App
4
+
5
+ def initialize(argv, folder, lang = :ru)
6
+ super(argv, folder, __dir__, lang)
7
+ end
8
+
9
+ def init_app
10
+ super
11
+ add_config('config.yml', :class)
12
+ end
13
+
14
+ end
@@ -0,0 +1,11 @@
1
+ -- Запуск приложения ---------------------------
2
+ Приложение: /Users/Stan/Documents/Development/RubyMine/cli_application/test/log/04_log_section_type_file_ok/app.rb
3
+ Имя скрипта: app.rb
4
+ Приложение запущено: 2018-01-07 16:47:13 +0300
5
+
6
+ -- Пользовательская секция ---------------------
7
+
8
+ -- Завершение приложения -----------------------
9
+ Приложение завершено: 2018-01-07 16:47:13 +0300 (время выполнения: 0.045 сек.)
10
+ Использование памяти: 40.0 Мбайт
11
+ Результат завершения: 0 (SUCCESS)
@@ -0,0 +1,33 @@
1
+ ---
2
+ :name: app.rb
3
+ :shortdescription: "Тестовый скрипт демонстрации CliApplication"
4
+ :version: '1.0'
5
+ :releasedate: '2018-01-06'
6
+ :timezone: Moscow
7
+ :last_started_at: '2018-01-07 16:47:13 +0300'
8
+ :folders:
9
+ :app: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/log/04_log_section_type_file_ok"
10
+ :class: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/log/04_log_section_type_file_ok"
11
+ :stat: "/Users/Stan/Documents/Development/RubyMine/cli_application/test/log/04_log_section_type_file_ok/stat"
12
+ :avg:
13
+ :starts: 21
14
+ :executed_at: 0.062094
15
+ :executed_at_human: 0.062094 секунд
16
+ :memory: 41897590
17
+ :last:
18
+ :started_at: '2018-01-07 16:47:13 +0300'
19
+ :executed_at: 0.044499
20
+ :executed_at_human: 0.044499 секунд
21
+ :memory: 40.0 Мбайт
22
+ :exitcode: 0
23
+ :last10:
24
+ - 2018-01-07 16:47:13 +0300,0,0.044499,40.0 Мбайт
25
+ - 2018-01-07 00:00:13 +0300,0,0.066548,40.4 Мбайт
26
+ - 2018-01-06 23:59:57 +0300,255,0.089557,39.7 Мбайт
27
+ - 2018-01-06 23:54:52 +0300,255,0.088694,40.0 Мбайт
28
+ - 2018-01-06 23:51:19 +0300,255,0.085997,39.9 Мбайт
29
+ - 2018-01-06 23:32:03 +0300,255,0.051075,40.2 Мбайт
30
+ - 2018-01-06 23:30:44 +0300,255,0.075102,39.7 Мбайт
31
+ - 2018-01-06 23:27:03 +0300,255,0.079105,40.1 Мбайт
32
+ - 2018-01-06 23:24:07 +0300,255,0.056074,40.1 Мбайт
33
+ - 2018-01-06 23:23:17 +0300,255,0.057794,40.2 Мбайт
metadata CHANGED
@@ -1,61 +1,61 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cli_application
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stan Zhuravlev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-04 00:00:00.000000000 Z
11
+ date: 2019-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">"
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.9'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">"
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.9'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">"
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">"
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: st_tools
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">"
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0.4'
48
- - - ">="
48
+ - - ">"
49
49
  - !ruby/object:Gem::Version
50
50
  version: '0.4'
51
51
  type: :development
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - ">"
55
+ - - "~>"
56
56
  - !ruby/object:Gem::Version
57
57
  version: '0.4'
58
- - - ">="
58
+ - - ">"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0.4'
61
61
  - !ruby/object:Gem::Dependency
@@ -100,6 +100,13 @@ files:
100
100
  - lib/cli_application/databases.rb
101
101
  - lib/cli_application/includes.rb
102
102
  - lib/cli_application/json_struct.rb
103
+ - lib/cli_application/locales/ru.yml
104
+ - lib/cli_application/log/README.md
105
+ - lib/cli_application/log/base.rb
106
+ - lib/cli_application/log/config.rb
107
+ - lib/cli_application/log/database.rb
108
+ - lib/cli_application/log/file.rb
109
+ - lib/cli_application/log/none.rb
103
110
  - lib/cli_application/mail.rb
104
111
  - lib/cli_application/mail_lib/base.rb
105
112
  - lib/cli_application/mail_lib/error.rb
@@ -123,6 +130,18 @@ files:
123
130
  - test/examples/7/app.rb
124
131
  - test/examples/7/mail/app-mail-2015-06-10.txt
125
132
  - test/examples/8/app.rb
133
+ - test/log/01_log_section_missing/app.rb
134
+ - test/log/01_log_section_missing/cli_example.rb
135
+ - test/log/02_log_section_type_wrong/app.rb
136
+ - test/log/02_log_section_type_wrong/cli_example.rb
137
+ - test/log/02_log_section_type_wrong/stat/app.yml
138
+ - test/log/03_log_section_type_none_ok/app.rb
139
+ - test/log/03_log_section_type_none_ok/cli_example.rb
140
+ - test/log/03_log_section_type_none_ok/stat/app.yml
141
+ - test/log/04_log_section_type_file_ok/app.rb
142
+ - test/log/04_log_section_type_file_ok/cli_example.rb
143
+ - test/log/04_log_section_type_file_ok/logs/app.log
144
+ - test/log/04_log_section_type_file_ok/stat/app.yml
126
145
  - test/stat/rdebug-ide
127
146
  - test/stat/test_app.yml
128
147
  - test/test_app.rb