Class: ColorTail::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/colortail/application.rb

Class Method Summary collapse

Class Method Details

.run!(*arguments) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/colortail/application.rb', line 10

def run!(*arguments)
   require 'fcntl'
    
   opt = ColorTail::Options.new(arguments) 
   filelist = opt[:files]
   options = opt[:options]
    
   # Deal with any/all options issues
   if opt[:invalid_argument]
       $stderr.puts opt[:invalid_argument]
       options[:help] = true
   end
    
   # Show the help menu if desired
   if options[:help]
       $stderr.puts version()
       $stderr.puts opt.opts
       return 1
   end
   
   # Show the version
   if options[:version]
       $stderr.puts version()
       return 1
   end

   
   # The meat of the program
   begin
       # Read the config file if it exists
       if File.exists?(options[:conf])
           config = ColorTail::Configuration.new(options[:conf])
           match_group = config.load_opts(options[:group])
       else
           # Create this to ensure we always have a value for this array
           match_group = Array.new
           match_group.push( 'default' => [] )
       end

       # Display the list of available groups and exit
       if options[:list]
           puts "The following match groups are available through your config files:"
           if config
               config.display_match_groups()
           else
               puts "  * default"
           end
           return 1
       end
       
       # Create the default logging object
       logger = ColorTail::Colorize.new()

       # Add the color match array if we aren't using the default
       if match_group.class == Array
           match_group.each do |matcher|
               logger.add_color_matcher( matcher )
           end
       else
           logger.add_color_matcher( match_group )
       end
       
       # Create an empty array of threads
       threads = Array.new
       
       # Set $stdin to be non-blocking
       $stdin.fcntl(Fcntl::F_SETFL,Fcntl::O_NONBLOCK)
       
       begin
           threads[0] = Thread.new {
               begin
                   $stdin.each_line do |line|
                       if options[:filename_prefix]
                           logger.log( nil, line, "STDIN: " )
                       else
                           logger.log( nil, line )
                       end
                   end
               rescue Errno::EAGAIN
                   # Remove this thread since we won't be reading from $stdin
                   threads.delete(0)
               end
           }.run
           
           # Check to see if there are files in the files array
           if filelist.size > 0
               # Before we go any further, check for existance of files
               @files_exist = false
               files = Hash.new
               filelist.each do |file|
                   filename = String.new
                   group = String.new
                   filename,group = file.split('#')
                   if group.nil?
                       files[filename] = options[:group]
                   else
                       files[filename] = group
                   end
                   
                   # Check for individual files and ignore file if doesn't exist
                   if File.exists?(filename)
                       @files_exist = true
                   else
                       $stderr.puts("#{filename} does not exist, skipping...")
                       filelist.delete(file)
                   end
               end
               
               # If we have no files, tell them and show the help
               if !@files_exist and (threads.class == Array.class and threads.size <= 2)
                   $stderr.puts "Please check to make sure the files exist ..."
                   $stderr.puts opt.opts
                   return 1
               end
               
               # Create a thread for each file
               files.each_pair do |filename, grouping|
                   threads.push Thread.new {
                       # Figure out if grouping exists, if not fall back to global default
                       if config.group_exists?(grouping)
                           # Create a new per file logger object per file
                           file_logger = ColorTail::Colorize.new()
                           
                           # Redefine match_group since we have a new grouping
                           match_group = config.load_opts(grouping)
                           
                           # Add the color match array if we aren't using the default
                           if match_group.class == Array
                               match_group.each do |matcher|
                                   file_logger.add_color_matcher( matcher )
                               end
                           else
                               file_logger.add_color_matcher( match_group )
                           end
                           
                       # There is no such group, so we fall back to the default here
                       else
                           file_logger = logger
                       end
                       
                       # Create the new tailer object
                       tailer = ColorTail::TailFile.new( filename )

                       # First display the last 10 lines of each file in ARGV
                       tailer.interval = 10
                       tailer.backward( 10 )

                       # Tail the file and show new lines
                       tailer.tail do |line|
                           if options[:filename_prefix]
                               file_logger.log( filename, line, "#{filename}: ")
                           else
                               file_logger.log( filename, line )
                           end
                       end
                   }.run
               end
           end
           
       end

       # Let the threads do their real work
       threads.each do |thread|
           thread.join
       end

   # If we get a CTRL-C, catch it (rescue) and send it for cleanup
   rescue Interrupt
       thread_cleanup(threads) if defined? threads
   rescue NoInputError
       $stderr.puts "Please enter a file to tail..."
       $stderr.puts opt.opts
       return 1
   end

   # We should never make it here, but just in case...
   return 0
end

.thread_cleanup(threads) ⇒ Object



189
190
191
192
193
194
195
196
197
# File 'lib/colortail/application.rb', line 189

def thread_cleanup(threads)
    if threads.class == Array.class and threads.size > 0
        threads.each do |thread|
            thread.kill
        end
    end
    $stderr.puts "Terminating..."
    exit
end

.versionObject



5
6
7
8
# File 'lib/colortail/application.rb', line 5

def version
    version = File.read("#{File.join(File.dirname(__FILE__), '..')}/../VERSION").chomp!
    "#{File.basename($0)} v#{version}"
end