dohruby 0.2.1 → 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. data/CHANGELOG +8 -0
  2. data/bin/config.rb +61 -0
  3. data/bin/create_database.rb +13 -6
  4. data/bin/gendata.rb +37 -0
  5. data/bin/migrate.rb +66 -0
  6. data/bin/{rcov-preprocess-files.rb → rcov_preprocess_files.rb} +1 -1
  7. data/bin/run_tests.rb +15 -5
  8. data/bin/update_rdoc.rb +28 -0
  9. data/dohapp_home +0 -0
  10. data/lib/doh/app/activate_database.rb +5 -12
  11. data/lib/doh/app/activate_logger.rb +29 -13
  12. data/lib/doh/app/config.rb +18 -0
  13. data/lib/doh/app/home.rb +3 -8
  14. data/lib/doh/app/init_runnable.rb +39 -8
  15. data/lib/doh/app/init_script.rb +19 -0
  16. data/lib/doh/app/init_unit_test.rb +4 -1
  17. data/lib/doh/app_no_stdio.rb +1 -1
  18. data/lib/doh/boot/app.rb +2 -0
  19. data/lib/doh/boot/app_pwd.rb +2 -0
  20. data/lib/doh/boot/find_dohruby.rb +5 -0
  21. data/lib/doh/boot/find_dohruby_18.rb +37 -0
  22. data/lib/doh/boot/find_dohruby_19.rb +58 -0
  23. data/lib/doh/boot/init_runnable.rb +2 -0
  24. data/lib/doh/boot/options.rb +2 -0
  25. data/lib/doh/core/array.rb +10 -0
  26. data/lib/doh/core/bigdecimal.rb +15 -0
  27. data/lib/doh/core/date.rb +73 -0
  28. data/lib/doh/core/deep_dup.rb +12 -0
  29. data/lib/doh/core/hash.rb +21 -0
  30. data/lib/doh/core/object.rb +6 -0
  31. data/lib/doh/core/require_local.rb +5 -0
  32. data/lib/doh/core/socket.rb +25 -0
  33. data/lib/doh/core/string.rb +34 -4
  34. data/lib/doh/core.rb +4 -1
  35. data/lib/doh/data/basic.rb +24 -19
  36. data/lib/doh/data/bulk.rb +28 -88
  37. data/lib/doh/data/catalog.rb +44 -0
  38. data/lib/doh/data/human.rb +50 -42
  39. data/lib/doh/data/make_global.rb +3 -0
  40. data/lib/doh/data/require_datagen.rb +2 -1
  41. data/lib/doh/home.rb +16 -0
  42. data/lib/doh/logger/email_acceptor.rb +6 -3
  43. data/lib/doh/logger/event.rb +19 -6
  44. data/lib/doh/logger/formatter.rb +22 -16
  45. data/lib/doh/logger/interface.rb +13 -0
  46. data/lib/doh/logger/iostream_acceptor.rb +3 -2
  47. data/lib/doh/logger/null_interface.rb +1 -0
  48. data/lib/doh/logger/proxy.rb +53 -0
  49. data/lib/doh/logger/socket_acceptor.rb +53 -0
  50. data/lib/doh/logger/socket_viewer.rb +64 -0
  51. data/lib/doh/logger/standard_interface.rb +46 -17
  52. data/lib/doh/logger/util.rb +18 -0
  53. data/lib/doh/logger.rb +2 -1
  54. data/lib/doh/logger_configure.rb +1 -1
  55. data/lib/doh/merb/db_session.rb +136 -0
  56. data/lib/doh/merb/form_helpers.rb +16 -0
  57. data/lib/doh/merb/login.rb +27 -12
  58. data/lib/doh/merb/merb_dohsession.rb +4 -0
  59. data/lib/doh/merb/notify_on_exception.rb +1 -1
  60. data/lib/doh/merb/session.rb +7 -0
  61. data/lib/doh/merb/source_ip.rb +10 -0
  62. data/lib/doh/merb.rb +0 -1
  63. data/lib/doh/mysql/abstract_row.rb +81 -0
  64. data/lib/doh/mysql/cache_connector.rb +11 -8
  65. data/lib/doh/mysql/connector_instance.rb +32 -5
  66. data/lib/doh/mysql/connector_util.rb +1 -0
  67. data/lib/doh/mysql/convert.rb +18 -0
  68. data/lib/doh/mysql/database_creator.rb +18 -5
  69. data/lib/doh/mysql/db_date.rb +2 -2
  70. data/lib/doh/mysql/default_type_guesser.rb +21 -4
  71. data/lib/doh/mysql/error.rb +3 -2
  72. data/lib/doh/mysql/handle.rb +144 -18
  73. data/lib/doh/mysql/hash_row.rb +13 -0
  74. data/lib/doh/mysql/load_sql.rb +1 -0
  75. data/lib/doh/mysql/metadata_util.rb +60 -19
  76. data/lib/doh/mysql/migrate.rb +122 -0
  77. data/lib/doh/mysql/migrate_check.rb +139 -0
  78. data/lib/doh/mysql/parse.rb +2 -0
  79. data/lib/doh/mysql/readonly_row.rb +11 -48
  80. data/lib/doh/mysql/require_dbtypes.rb +8 -0
  81. data/lib/doh/mysql/smart_row.rb +156 -0
  82. data/lib/doh/mysql/to_sql.rb +12 -0
  83. data/lib/doh/mysql/typed_row_builder.rb +4 -3
  84. data/lib/doh/mysql/types.rb +33 -0
  85. data/lib/doh/mysql/unquoted.rb +8 -0
  86. data/lib/doh/mysql/version.rb +102 -0
  87. data/lib/doh/mysql/virtual.rb +17 -0
  88. data/lib/doh/mysql/writable_row.rb +58 -0
  89. data/lib/doh/mysql.rb +2 -1
  90. data/lib/doh/paypal/paypal.rb +20 -0
  91. data/lib/doh/paypal/pdt.rb +14 -0
  92. data/lib/doh/paypal.rb +1 -0
  93. data/lib/doh/rails/form_helpers.rb +53 -0
  94. data/lib/doh/rails/login.rb +143 -0
  95. data/lib/doh/test/error_acceptor.rb +1 -1
  96. data/lib/doh/test/run_tests.rb +48 -43
  97. data/lib/doh/test/setup_once.rb +15 -0
  98. data/lib/doh/test/test_result.rb +7 -0
  99. data/lib/doh/unit_test.rb +6 -0
  100. data/lib/doh/util/banking_workday.rb +16 -12
  101. data/lib/doh/util/class_basename.rb +10 -0
  102. data/lib/doh/util/current_date.rb +18 -41
  103. data/lib/doh/util/doh_socket.rb +56 -0
  104. data/lib/doh/util/email.rb +18 -0
  105. data/lib/doh/util/file_edit.rb +64 -0
  106. data/lib/doh/util/http_helper.rb +107 -0
  107. data/lib/doh/util/internal_ip.rb +1 -1
  108. data/lib/doh/util/jsval.rb +13 -0
  109. data/lib/doh/util/post_hash.rb +14 -0
  110. data/lib/doh/util/xml_util.rb +48 -0
  111. data/test/core/tc_array.rb +12 -0
  112. data/test/core/tc_date.rb +53 -0
  113. data/test/core/tc_deep_dup.rb +69 -0
  114. data/test/core/tc_hash.rb +28 -0
  115. data/test/core/tc_socket.rb +30 -0
  116. data/test/core/tc_string.rb +15 -22
  117. data/test/local_tests.rb +3 -0
  118. data/test/local_tests_including_slow.rb +4 -0
  119. data/test/logger/tc_acceptor.rb +23 -6
  120. data/test/logger/tc_event.rb +1 -1
  121. data/test/logger/tc_formatter.rb +3 -2
  122. data/test/logger/tc_socket_viewer_acceptor.rb +48 -0
  123. data/test/mysql/001_down.sql +1 -0
  124. data/test/mysql/001_up.sql +4 -0
  125. data/test/mysql/002_down.sql +1 -0
  126. data/test/mysql/002_up.sql +1 -0
  127. data/test/mysql/tc_connector_instance.rb +8 -8
  128. data/test/mysql/tc_convert.rb +45 -0
  129. data/test/mysql/tc_handle.rb +94 -2
  130. data/test/mysql/tc_metadata_util.rb +50 -0
  131. data/test/mysql/tc_migrate.rb +50 -0
  132. data/test/mysql/tc_parse.rb +3 -1
  133. data/test/mysql/tc_readonly_row.rb +14 -10
  134. data/test/mysql/tc_smart_row.rb +22 -0
  135. data/test/mysql/tc_to_sql.rb +20 -0
  136. data/test/mysql/tc_types.rb +32 -0
  137. data/test/mysql/tc_unquoted.rb +1 -0
  138. data/test/mysql/tc_writable_row.rb +22 -0
  139. data/test/ts_core.rb +4 -0
  140. data/test/ts_logger.rb +4 -0
  141. data/test/ts_mysql.rb +6 -0
  142. data/test/ts_util.rb +6 -0
  143. data/test/util/slow_doh_socket.rb +102 -0
  144. data/test/util/tc_banking_workday.rb +18 -0
  145. data/test/util/tc_file_edit.rb +54 -0
  146. data/test/util/tc_jsval.rb +12 -0
  147. data/test/util/tc_to_display.rb +14 -0
  148. data/test/util/tc_xml_util.rb +17 -0
  149. metadata +130 -39
  150. data/README +0 -4
  151. data/lib/doh/merb/post_hash.rb +0 -26
  152. data/lib/doh/mysql/db_null.rb +0 -24
  153. data/lib/doh/mysql/hash_util.rb +0 -56
  154. data/test/mysql/tc_hash_util.rb +0 -23
@@ -3,124 +3,132 @@ require 'doh/data/bulk'
3
3
 
4
4
  module DohData
5
5
 
6
- def self.random_first_name
6
+ def random_first_name
7
7
  random_element(@@first_names)
8
8
  end
9
9
 
10
- def self.random_last_name
10
+ def random_last_name
11
11
  random_element(@@last_names)
12
12
  end
13
13
 
14
- def self.random_generation
14
+ def random_generation
15
15
  random_element(@@generation_options)
16
16
  end
17
17
 
18
- def self.random_us_state_abbreviation
18
+ def random_us_state_abbreviation
19
19
  random_element(@@us_state_abbreviations)
20
20
  end
21
21
 
22
- def self.random_us_state_long_name
22
+ def random_us_state_long_name
23
23
  random_element(@@us_state_long_names)
24
24
  end
25
25
 
26
- def self.random_occupation
26
+ def random_occupation
27
27
  random_element(@@occupations)
28
28
  end
29
29
 
30
- def self.random_us_state
31
- (rand(2) == 0) ? DohData::random_us_state_abbreviation : DohData::random_us_state_long_name
30
+ def random_us_state
31
+ (random_int(2) == 0) ? DohData::random_us_state_abbreviation : DohData::random_us_state_long_name
32
32
  end
33
33
 
34
- def self.random_us_zip
35
- random_digits(5) + ((rand(4) == 0) ? '-' + random_digits(4) : '')
34
+ def random_us_zip
35
+ random_digits(5) + ((random_int(4) == 0) ? '-' + random_digits(4) : '')
36
36
  end
37
37
 
38
- def self.random_us_phone
38
+ def random_us_phone
39
39
  random_range(200,999).to_s + '-' + random_digits(3) + '-' + random_digits(4)
40
40
  end
41
41
 
42
- def self.random_full_name
42
+ def random_full_name
43
43
  random_first_name + ' ' + random_last_name
44
44
  end
45
45
 
46
- def self.random_email(first_name = nil, last_name = nil)
46
+ def random_email(first_name = nil, last_name = nil)
47
+ domain = '@' + random_element(@@email_domains) + '.' + random_element(@@email_tlds)
48
+ max_name_size = 50 - domain.size
49
+
47
50
  if first_name || last_name
48
51
  name = ''
49
- name += first_name.slice(0, random_element(1, 1, 1, 1, first_name.size)) if first_name
50
- name += random_element('', '.') if first_name && last_name
51
- name += last_name.slice(0, random_element(1, last_name.size, last_name.size)) if last_name
52
- name += random_range(11, 358).to_s
52
+ name += first_name.slice(0, random_range(1, first_name.size)) if first_name
53
+ name += random_element('', '.', '_') if first_name && last_name
54
+ name += last_name.slice(0, random_range(1, last_name.size)) if last_name
55
+ max_num_size = max_name_size - name.size
56
+ name += random_digits(random_range([7, max_num_size].min, [12, max_num_size].min))
53
57
  else
54
- name = random_letters(random_range(3, 12))
58
+ name_size = random_range([12, max_name_size].min, [16, max_name_size].min)
59
+ name = random_letters(name_size)
55
60
  end
56
- name + '@' + random_element(@@email_domains) + '.' + random_element(@@email_tlds)
61
+ name + domain
62
+ end
63
+
64
+ def ssn_areas
65
+ @@ssn_areas ||= @@ssn_area_highgroups.keys
57
66
  end
58
67
 
59
- def self.random_ssn
60
- random_row = random_array_element(@@ssn_highgroups)
61
- highgroup = random_row[0]
62
- area = random_element(random_row[1])
68
+ def random_ssn
69
+ area = random_element(ssn_areas)
70
+ highgroup = @@ssn_area_highgroups[area]
63
71
  highgroup_index = @@ssn_group_order.index(highgroup)
64
72
  possible_groups = @@ssn_group_order.slice(0..highgroup_index)
65
73
  group = random_element(possible_groups)
66
74
  area.to_s.rjust(3, '0') + group.to_s.rjust(2, '0') + random_range(1, 9999).to_s.rjust(4, '0')
67
75
  end
68
76
 
69
- def self.random_city
77
+ def random_city
70
78
  random_element(@@cities)
71
79
  end
72
80
 
73
- def self.random_street_name
81
+ def random_street_name
74
82
  random_element(@@street_names)
75
83
  end
76
84
 
77
- def self.random_street_type
85
+ def random_street_type
78
86
  random_element(@@street_types)
79
87
  end
80
88
 
81
- def self.random_street_number
82
- weight = rand(10)
89
+ def random_street_number
90
+ weight = random_int(10)
83
91
  if weight > 8
84
- rand(50000)
92
+ random_int(50000)
85
93
  elsif weight > 5
86
- rand(10000)
94
+ random_int(10000)
87
95
  elsif weight > 3
88
- rand(1000)
96
+ random_int(1000)
89
97
  else
90
- rand(100)
98
+ random_int(100)
91
99
  end
92
100
  end
93
101
 
94
- def self.random_street
102
+ def random_street
95
103
  random_street_number.to_s + ' ' + random_element('N','E','S','W') + ' ' + random_street_name + ' ' + random_street_type
96
104
  end
97
105
 
98
- def self.random_birthday
99
- Date.new(1928 + rand(56), rand(12) + 1, rand(27) + 1)
106
+ def random_birthday
107
+ Date.new(1928 + random_int(56), random_int(12) + 1, random_int(27) + 1)
100
108
  end
101
109
 
102
- def self.random_bank_routing_number
110
+ def random_bank_routing_number
103
111
  random_element(@@bank_routing_numbers)
104
112
  end
105
113
 
106
- def self.random_bank_account_number(max_size = 17)
114
+ def random_bank_account_number(max_size = 17)
107
115
  random_digits(random_range(5, max_size))
108
116
  end
109
117
 
110
- def self.random_employer_name
118
+ def random_employer_name
111
119
  random_element(@@employers)
112
120
  end
113
121
 
114
- def self.random_relation
122
+ def random_relation
115
123
  random_element(['cousin', 'mother', 'father', 'aunt', 'uncle', 'brother', 'sister', 'son', 'daughter'])
116
124
  end
117
125
 
118
- def self.random_country_code
126
+ def random_country_code
119
127
  random_element(['USA', 'MEX', 'CAN'])
120
128
  end
121
129
 
122
- def self.random_ip_address
123
- "#{rand(256)}.#{rand(256)}.#{rand(256)}.#{rand(256)}"
130
+ def random_ip_address
131
+ "#{random_int(256)}.#{random_int(256)}.#{random_int(256)}.#{random_int(256)}"
124
132
  end
125
133
 
126
134
  end
@@ -0,0 +1,3 @@
1
+ class Object
2
+ include DohData
3
+ end
@@ -1,7 +1,8 @@
1
1
  module DohData
2
2
 
3
3
  def self.require_datagen
4
- require('datagen') if File.exist?(File.join(DohApp::home, 'lib/datagen.rb'))
4
+ lib_datagen_file = File.join(DohApp::home, 'lib/datagen.rb')
5
+ require(lib_datagen_file) if File.exist?(lib_datagen_file)
5
6
  end
6
7
 
7
8
  end
data/lib/doh/home.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Doh
2
+ def self.home
3
+ @@home ||= find_file_in_parents(File.dirname(__FILE__), 'dohapp_home')
4
+ end
5
+
6
+ def self.find_file_in_parents(dir, filename, max_tries = 20)
7
+ path = File.expand_path(dir)
8
+ raise "unable to find #{filename.inspect}" if (path == '/') || (max_tries <= 0)
9
+
10
+ if File.exist?(File.join(path, filename))
11
+ return path
12
+ else
13
+ return find_file_in_parents(File.join(path, '..'), filename, max_tries - 1)
14
+ end
15
+ end
16
+ end
@@ -1,13 +1,14 @@
1
1
  require 'net/smtp'
2
+ require 'socket'
2
3
 
3
4
  module DohLogger
4
5
 
5
6
  def self.exception_email_format
6
- "%severity: %msg\nlogfile_name: #@logfile_name\nsource_ip: %source_ip\nexception: %exception\nstack:\n%call_stack"
7
+ "%severity (%location): %msg\nlogfile_name: %logfile_name\nsource_ip: %source_ip\nhostname: %hostname (%internal_ip)\nexception: %exception\nstack:\n%call_stack"
7
8
  end
8
9
 
9
10
  def self.exceptionless_email_format
10
- "%severity: %msg\nlogfile_name: #@logfile_name\nsource_ip: %source_ip\n"
11
+ "%severity (%location): %msg\nlogfile_name: %logfile_name\nsource_ip: %source_ip\nhostname: %hostname (%internal_ip)\n"
11
12
  end
12
13
 
13
14
  class EmailAcceptor
@@ -18,16 +19,18 @@ class EmailAcceptor
18
19
  @logfile_name = logfile_name
19
20
  @subject_formatter = Formatter.new(subject_format || "%severity - %msg")
20
21
  @body_formatter = Formatter.new(body_format)
22
+ @body_formatter.register_format('%logfile_name') {|event| @logfile_name}
21
23
  end
22
24
 
23
25
  def log(event)
24
26
  subject = @subject_formatter.replace(event)
25
27
  body = @body_formatter.replace(event)
26
- msg = "Subject:#{subject}\nContent-Type: text/plain\n\n#{body}"
28
+ msg = "Subject:#{subject}\nFrom:#{@from_address}\nTo:#{@to_addresses.join(', ')}\nContent-Type: text/plain\n\n#{body}"
27
29
  Net::SMTP.start(@smtp_server) do |smtp|
28
30
  begin
29
31
  smtp.send_message(msg, @from_address, @to_addresses)
30
32
  rescue Exception => excpt
33
+ puts "got exception: #{excpt.inspect}"
31
34
  end
32
35
  end
33
36
  end
@@ -4,20 +4,33 @@ require 'ostruct'
4
4
 
5
5
  module DohLogger
6
6
 
7
- class Event < OpenStruct
8
- def initialize(severity, msg, excpt = nil)
9
- msg = msg.gsub(/\n/, '\n').gsub(/\r/, '\r').gsub(/\t/, '\t').firstn(4096)
10
- super('severity' => severity, 'msg' => msg, 'exception' => excpt, 'time' => Time.now)
7
+ class Event
8
+ attr_accessor :severity, :msg, :location, :exception, :time, :pid
9
+
10
+ def initialize(severity, msg, location = '', excpt = nil, literal = false)
11
+ msg = msg.gsub(/\n/, '\n').gsub(/\r/, '\r').gsub(/\t/, '\t') if !literal
12
+ @severity = severity
13
+ @msg = msg.firstn(4096)
14
+ @location = location
15
+ @exception = excpt
16
+ @time = Time.now
11
17
  end
12
18
 
13
19
  def call_stack
14
- excpt = self.exception
15
- excpt ? excpt.backtrace : caller
20
+ @exception ? @exception.backtrace : caller
16
21
  end
17
22
 
18
23
  def source_ip
19
24
  Doh::source_ip
20
25
  end
26
+
27
+ def inspect
28
+ result = "{'severity' => #{@severity.inspect}, 'msg' => #{@msg.inspect}, 'location' => #{@location.inspect} 'exception' => #{@exception.inspect} 'time' => #{@time.inspect}}"
29
+ if @exception
30
+ result += ", backtrace: #{@exception.backtrace.inspect}"
31
+ end
32
+ result
33
+ end
21
34
  end
22
35
 
23
36
  end
@@ -1,25 +1,18 @@
1
1
  require 'doh/logger/severity'
2
+ require 'doh/util/internal_ip'
2
3
 
3
4
  module DohLogger
4
5
 
6
+ class OptimizedStandardFormatter
7
+ def replace(event)
8
+ "#{event.time.strftime("%Y-%m-%d %H:%M:%S.") << "%03d" % (event.time.usec / 1000)} [#{DohLogger::severity_string(event.severity)}] (#{event.location}) : #{event.msg}"
9
+ end
10
+ end
11
+
5
12
  class Formatter
6
13
  def initialize(template)
7
14
  @template = template
8
15
  @formats = {}
9
- register_format('%severity') {|event| DohLogger::severity_string(event.severity)}
10
- register_format('%msg') {|event| event.msg}
11
- register_format('%time') {|event| event.time.strftime("%H:%M:%S.") << "%03d" % (event.time.usec / 1000)}
12
- register_format('%datetime') {|event| event.time.strftime("%Y-%m-%d %H:%M:%S.") << "%03d" % (event.time.usec / 1000)}
13
- register_format('%call_stack') {|event| event.call_stack.join("\n")}
14
- register_format('%source_ip') {|event| event.source_ip}
15
-
16
- register_format('%exception') do |event|
17
- if event.exception.nil?
18
- ''
19
- else
20
- event.exception.class.to_s + ' -- ' + event.exception.to_s
21
- end
22
- end
23
16
  end
24
17
 
25
18
  def register_format(field, &proc)
@@ -27,9 +20,22 @@ class Formatter
27
20
  end
28
21
 
29
22
  def replace(event)
30
- @formats.inject(@template) do |sum, elem|
31
- sum = sum.gsub(elem[0], elem[1].call(event))
23
+ result = @template.dup
24
+ result.gsub!('%severity', DohLogger::severity_string(event.severity)) if result =~ /%severity/
25
+ result.gsub!('%msg', event.msg) if result =~ /%msg/
26
+ result.gsub!('%location', event.location) if result =~ /%location/
27
+ result.gsub!('%time', event.time.strftime("%H:%M:%S.") << "%03d" % (event.time.usec / 1000)) if result =~ /%time/
28
+ result.gsub!('%datetime', event.time.strftime("%Y-%m-%d %H:%M:%S.") << "%03d" % (event.time.usec / 1000)) if result =~ /%datetime/
29
+ result.gsub!('%call_stack', event.call_stack.join("\n")) if result =~ /%call_stack/
30
+ result.gsub!('%source_ip', event.source_ip) if result =~ /%source_ip/
31
+ result.gsub!('%hostname', Socket.gethostname) if result =~ /%hostname/
32
+ result.gsub!('%internal_ip', Doh::internal_ip) if result =~ /%internal_ip/
33
+ result.gsub!('%exception', event.exception.nil? ? '' : "#{event.exception.class} -- #{event.exception}") if result =~ /%exception/
34
+
35
+ @formats.each do |elem|
36
+ result.gsub!(elem[0]) {elem[1].call(event)}
32
37
  end
38
+ result
33
39
  end
34
40
  end
35
41
 
@@ -11,4 +11,17 @@ def self.log
11
11
  @@logger_interface
12
12
  end
13
13
 
14
+ @@save_logger_interface = nil
15
+ def self.disable_logging
16
+ return if @@logger_interface.is_a?(DohLogger::NullInterface)
17
+ @@save_logger_interface = @@logger_interface
18
+ @@logger_interface = DohLogger::NullInterface.new
19
+ end
20
+
21
+ def self.enable_logging
22
+ return if @@save_logger_interface.nil? || @@save_logger_interface.is_a?(DohLogger::NullInterface)
23
+ @@logger_interface = @@save_logger_interface
24
+ @@save_logger_interface = nil
25
+ end
26
+
14
27
  end
@@ -3,10 +3,11 @@ require 'doh/logger/formatter'
3
3
  module DohLogger
4
4
 
5
5
  class IOStreamAcceptor
6
+ attr_reader :ios
6
7
  def initialize(ios = nil, format = nil, error_format = nil)
7
8
  @ios = ios || STDOUT
8
- @standard_formatter = Formatter.new(format || "%datetime [%severity] : %msg")
9
- @error_formatter = Formatter.new(error_format || format || "%datetime [%severity] : %msg\nexception: %exception\nstack:\n%call_stack")
9
+ @standard_formatter = format ? Formatter.new(format) : OptimizedStandardFormatter.new
10
+ @error_formatter = Formatter.new(error_format || format || "%datetime [%severity] (%location) : %msg\nexception: %exception\nstack:\n%call_stack")
10
11
  end
11
12
 
12
13
  def flush_always(flag = true)
@@ -1,6 +1,7 @@
1
1
  module DohLogger
2
2
 
3
3
  class NullInterface
4
+ attr_accessor :literal
4
5
  def fatal(*ignore) end
5
6
  def error(*ignore) end
6
7
  def notify(*ignore) end
@@ -0,0 +1,53 @@
1
+ require 'doh/logger/interface'
2
+
3
+ module DohLogger
4
+
5
+ class Proxy
6
+ def initialize(location)
7
+ @location = location
8
+ end
9
+
10
+ def fatal(msg, excpt = nil)
11
+ Doh::log.fatal(msg, excpt, @location)
12
+ end
13
+
14
+ def error(msg, excpt = nil)
15
+ Doh::log.error(msg, excpt, @location)
16
+ end
17
+
18
+ def notify(msg)
19
+ Doh::log.notify(msg, @location)
20
+ end
21
+
22
+ def warn(msg)
23
+ Doh::log.warn(msg, @location)
24
+ end
25
+
26
+ def info(msg)
27
+ Doh::log.info(msg, @location)
28
+ end
29
+
30
+ def debug(msg)
31
+ Doh::log.debug(msg, @location)
32
+ end
33
+
34
+ def literal
35
+ Doh::log.literal = true
36
+ yield
37
+ Doh::log.literal = false
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ class Module
44
+ def dohlog
45
+ @dohlog ||= DohLogger::Proxy.new(self.to_s)
46
+ end
47
+ end
48
+
49
+ class Object
50
+ def dohlog
51
+ self.class.dohlog
52
+ end
53
+ end
@@ -0,0 +1,53 @@
1
+ require 'socket'
2
+ require 'doh/core/socket'
3
+ require 'yaml'
4
+ require 'thread'
5
+
6
+ module DohLogger
7
+
8
+ # this class accepts log events, and posts them to a socket
9
+ # this is typically used in conjunction with socket_viewer.rb
10
+ # to do remote debugging
11
+ class SocketAcceptor
12
+ def initialize(host = '127.0.0.1', port = SocketAcceptor::default_port)
13
+ @host = host
14
+ @port = port
15
+ @last_connect_attempt = nil
16
+ end
17
+
18
+ def self.default_port
19
+ 2377
20
+ end
21
+
22
+ def five_seconds
23
+ 5.0/86440
24
+ end
25
+
26
+ # don't attempt to connect more than once every 5 seconds
27
+ def connect_socket(how_often = five_seconds)
28
+ if @sock || @last_connect_attempt && @last_connect_attempt >= (DateTime.now - how_often)
29
+ return
30
+ end
31
+ @last_connect_attempt = DateTime.now
32
+ @sock ||= TCPSocket.new(@host, @port)
33
+ end
34
+
35
+ def log(event)
36
+ begin
37
+ connect_socket
38
+ return if !@sock
39
+ event.pid = Process.pid
40
+ if event.exception
41
+ newevent = event.dup
42
+ newevent.exception = Exception.new("Exception(#{event.exception.class}): " + event.exception.to_s)
43
+ newevent.exception.set_backtrace(event.exception.backtrace)
44
+ event = newevent
45
+ end
46
+ @sock.write_object(Marshal::dump(event))
47
+ rescue Errno::ECONNREFUSED => e
48
+ #ignore silently?
49
+ end
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,64 @@
1
+ require 'doh/core/socket'
2
+ require 'ostruct'
3
+ require 'thread'
4
+ require 'yaml'
5
+ require 'doh/logger/socket_acceptor'
6
+ require 'doh/logger/event'
7
+
8
+ module DohLogger
9
+
10
+ # this class accepts log events through potentially multiple sockets
11
+ # combining the events from the multiple sockets as they're received into a single event stream
12
+ # this is typically used in conjunction with socket_acceptor.rb
13
+ # to do remote debugging
14
+ class SocketViewer
15
+ def initialize(port = DohLogger::SocketAcceptor::default_port)
16
+ @events = Queue.new
17
+ @server = TCPServer.new(port)
18
+ end
19
+
20
+ def shutdown
21
+ @server.close
22
+ @events.enq(:finished)
23
+ end
24
+
25
+ def accept_connections
26
+ thread_socks = []
27
+ begin
28
+ loop do
29
+ sock = @server.accept
30
+ thread_socks.push([Thread.new{handle_events_for_sock(sock)}, sock])
31
+ end
32
+ rescue IOError => e
33
+ ensure
34
+ thread_socks.each do |elem|
35
+ elem[1].close
36
+ elem[0].join
37
+ end
38
+ end
39
+ end
40
+
41
+ def handle_events_for_sock(sock)
42
+ begin
43
+ begin
44
+ obj = sock.read_object
45
+ @events.enq(obj)
46
+ end until sock.closed?
47
+ rescue IOError => e
48
+ #silently ignore IOErrors?
49
+ end
50
+ thread.join
51
+ end
52
+
53
+ def handle_events
54
+ thread = Thread.new {accept_connections}
55
+ loop do
56
+ event_str = @events.deq
57
+ break if event_str == :finished
58
+ event = Marshal::load(event_str)
59
+ yield event
60
+ end
61
+ end
62
+ end
63
+
64
+ end
@@ -4,44 +4,73 @@ require 'doh/logger/event'
4
4
  module DohLogger
5
5
 
6
6
  class StandardInterface
7
+ attr_accessor :literal
7
8
  def initialize(scheduler)
8
9
  @scheduler = scheduler
9
10
  @acceptors = []
11
+ @disabled_acceptors = []
10
12
  end
11
13
 
12
- def fatal(msg, excpt = nil)
13
- add(FATAL, msg, excpt)
14
+ # temporarily have this ordering of arguments, until all old style calls are switched
15
+ def fatal(msg, excpt = nil, location = '')
16
+ add(FATAL, msg, location, excpt)
14
17
  end
15
18
 
16
- def error(msg, excpt = nil)
17
- add(ERROR, msg, excpt)
19
+ # temporarily have this ordering of arguments, until all old style calls are switched
20
+ def error(msg, excpt = nil, location = '')
21
+ add(ERROR, msg, location, excpt)
18
22
  end
19
23
 
20
- def notify(msg)
21
- add(NOTIFY, msg)
24
+ def notify(msg, location = '')
25
+ add(NOTIFY, msg, location)
22
26
  end
23
27
 
24
- def warn(msg)
25
- add(WARN, msg)
28
+ def warn(msg, location = '')
29
+ add(WARN, msg, location)
26
30
  end
27
31
 
28
- def info(msg)
29
- add(INFO, msg)
32
+ def info(msg, location = '')
33
+ add(INFO, msg, location)
30
34
  end
31
35
 
32
- def debug(msg)
33
- add(DEBUG, msg)
36
+ def debug(msg, location = '')
37
+ add(DEBUG, msg, location)
34
38
  end
35
39
 
36
- def add_acceptor(severity_threshold, acceptor, exact_severity_only = nil)
37
- @acceptors.push([severity_threshold, acceptor, exact_severity_only])
40
+ def add_acceptor(severity_threshold, acceptor, exact_severity_only = nil, locations_to_exclude = nil, include_only_locations = nil)
41
+ @acceptors.push([severity_threshold, acceptor, exact_severity_only, locations_to_exclude, include_only_locations])
42
+ end
43
+
44
+ def disable_acceptors()
45
+ to_disable = @acceptors.inject([]) do |sum, acceptor|
46
+ sum.push(acceptor) if yield(acceptor)
47
+ sum
48
+ end
49
+ @disabled_acceptors.concat(to_disable)
50
+ @acceptors.reject! {|elem| to_disable.include?(elem)}
51
+ end
52
+
53
+ def enable_acceptors()
54
+ to_enable = @disabled_acceptors.inject([]) do |sum, acceptor|
55
+ sum.push(acceptor) if yield(acceptor)
56
+ sum
57
+ end
58
+ @acceptors.concat(to_enable)
59
+ @disabled_acceptors.reject! {|elem| to_enable.include?(elem)}
38
60
  end
39
61
 
40
62
  private
41
- def add(severity, msg, excpt = nil)
63
+ def add(severity, msg, location, excpt = nil)
42
64
  included = []
43
- @acceptors.each {|elem| included.push(elem[1]) if (severity >= elem[0] && !elem[2]) || severity == elem[0]}
44
- @scheduler.push(included, Event.new(severity, msg, excpt))
65
+ @acceptors.each do |severity_threshold, acceptor, exact_severity_only, locations_to_exclude, include_only_locations|
66
+ if (((severity >= severity_threshold && !exact_severity_only) || severity == severity_threshold) &&
67
+ (!locations_to_exclude || !locations_to_exclude.find {|exc_loc| location.start_with?(exc_loc)}) &&
68
+ (!include_only_locations || include_only_locations.find {|inc_loc| location.start_with?(inc_loc)})
69
+ )
70
+ included.push(acceptor)
71
+ end
72
+ end
73
+ @scheduler.push(included, Event.new(severity, msg, location, excpt, @literal)) if included.size > 0
45
74
  end
46
75
  end
47
76
 
@@ -4,4 +4,22 @@ def self.default_logfile_name
4
4
  File.basename($PROGRAM_NAME, '.rb') + '.log'
5
5
  end
6
6
 
7
+ class Proxy
8
+ def debug_options(shortname = 'd', longname = 'debug')
9
+ #note -- in order to use this right now you have to include these debug_options in your options hash, and then include a line like this:
10
+ #dohlog.disable_stdout unless OPTS.debug
11
+ {'debug' => [nil, "-#{shortname}", "--#{longname}", 'if specified, will display console debugging instead of just going to the file']}
12
+ end
13
+ def disable_stdout
14
+ Doh::log.disable_acceptors do |acceptor|
15
+ acceptor[1].ios == STDOUT
16
+ end
17
+ end
18
+ def enable_stdout
19
+ Doh::log.enable_acceptors do |acceptor|
20
+ acceptor[1].ios == STDOUT
21
+ end
22
+ end
23
+ end
24
+
7
25
  end
data/lib/doh/logger.rb CHANGED
@@ -1 +1,2 @@
1
- require 'doh/logger/interface'
1
+ require 'doh/logger/proxy'
2
+ require 'doh/logger/util'