I have some code I am maintaining that is using the logging ruby gem. I would like to use the linux logrotate tool instead of the gem to rotate the logs. I'm using it inside some custom code to create separate log streams.
require 'logging'
[...]
def create_logger(name)
logger = Logging.logger[name]
Is there a way I can turn off log rotation after the logger object is created?
logger.age = 0 is not working.
The source code has good documentation, which only mentions setting rotation strategy on initialization, I don't think changing an existing instance's rotation strategy is a good idea as it could have unintended consequences.
But, you could close the existing logger with logger.close and reopen it later with logger.reopen.
Related
For a blog, I put together an inline tag that pulls header information from a specified webpage. It works, but I need to add caching, so that I'm not making redundant network calls.
I'd like a tighter debugging cycle than restarting the server and waiting for a rebuild, but running the plugin as Ruby code reports uninitialized constant Liquid (NameError). That makes sense, since it isn't required, and wouldn't run, since the plugin is just a class definition.
So, I tried creating some scaffolding to run the code, or what I thought would be scaffolding, anyway.
require 'liquid'
require_relative '../_plugins/header.rb'
ht = HeaderInlineTag.new
ht.initialize 'header', 'some path'
puts ht.render()
This produces...
_test/header.rb:4:in `<main>': private method `new' called for HeaderInlineTag:Class (NoMethodError)
Considering the possibility that initialize() might be run to create objects, I combined the first two lines of code, but that didn't work, either. Same error, different function name. The plugin doesn't mark anything as private, and declaring the methods public doesn't change anything.
What more is needed to test the plugin without carrying around the entire blog?
The solution was beyond my Ruby knowledge, but mostly straightforward, once I connected the pieces of information floating around.
First, this existing answer is about a specific issue dealing with Rails, but incidentally shows how to deal with private new methods: Call them through send, as in HeaderInlineTag.send :new.
Then, this indirect call to .new() now (of course) calls .initialize(), meaning that it needs the three parameters that are required by any plugin. Two parameters are for the testing itself, so they're easy. The third is a parse context. Documentation on writing Jekyll plugins is never clear on what the parse context actually is, since it gets sent automatically as part of the build process. However, some research and testing turns up Liquid::ParseContext as the culprit.
Finally, .render() also takes the ParseContext value.
Therefore, the the test scaffold should look something like this.
require 'liquid'
require_relative '../_plugins/header.rb'
context = Liquid::ParseContext.new
ht = HeaderInlineTag.send :new, 'header', 'some path...', context
puts ht.render context
I can call this from my blog's root folder with ruby _test/header.rb, and it prints the plugin's output. I can now update this script to pull the parameters from the command line or a CSV file, depending on the tests required.
I'm creating an app using Flutter that has around 1500+ predefined colors and gradients.
I was wondering should I create a configuration file that always loads at the beginning of the app or should I create a class that has static final/const variables such as map+list?
Which one would be more memory efficient, less error prone and code friendly?
Any suggestions?
Thanks a lot!
Thanks for all the comments. Now since I don’t need to do update OTA, I decided to create a class with static map+list combination
I found the benefits are:
1. Less error prone because the naming will be checked by editor.
2. Only loaded in pages where we need it.
3. Compared to reading from a JSON files, it doesn’t need async functions to get the data thus faster. Because File reading is an I/O operation
I have a class that reads from a DB on startup. I'd prefer to be able to store it in the session, but I get the following error when trying to do so:
ERROR TypeError: no marshal_dump is defined for class Mutex
Is what I'm doing possible/reasonable? If so how should I go about doing it? If not, whats a good alternative to storing the class instance in the session? Currently my workaround is just instantiating it whenever I need to use it, but that doesn't strike me as a good solution or one that will be able to scale.
A good alternative is to store the id of the record in the session. Then when you need that data again you'd use a helper to return the data either from memory or from the database. A perfect example is the pattern used in current_user helper methods found in many ruby authentication gems. You could modify this helper to use a cache layer if you find it to be a bottleneck, but I'd leave that as an optimization after the fact.
Issues of having to get the object into a marshaled format that will live happily in a session, there are issues with storage space, stale data and possibly unintentional exposure to confidential data.
I have an ActiveRecord based application that is used via command line utilities. Having the models namespaced in such an application is advantageous for keeping the Object namespace clean.
I'm starting to build a rails application around these ActiveRecord models and, though I have overcome some of my initial troubles with using models in a namespace, I'm finding things are more verbose than I'd like.
What I want is to programmaticaly set a namespace for my ActiveRecord classes when used in the command line utilities and to programmaticaly not set a namespace for these models when used in the Rails app.
I know that the files themselves could be altered at runtime before being required, but I'm looking for something in the Ruby language itself to accomplish this cleanly.
hard to offer a great suggestion without seeing some code, but here are two possibilities.
It sounds like you have two clients for this code. Maybe make it an engine (just a fancy gem), you can add your paths to autoload paths, then use it from the gem without all the railsy crap getting in the way.
Maybe create a constant then reopen it in the models:
in some initializer
ActualNamespace = Class.new
DynamicNamespace = ActualNamespace
in your model file
class DynamicNamespace
class MyModel
end
end
DynamicNamespace::MyModel # => ActualNamespace::MyModel
Then for your command line app
DynamicNamespace = Object
Which is the same as not having a namespace:
DynamicNamespace::MyModel # => MyModel
Now you might wind up having difficulties with some of the Rails magic, which is largely based on reflection. I don't totally know what you'll face, but I'd expect forms to start generating the wrong keys when submitting data. You can probably fix this by defining something DynamicNamespace.name or something along those lines.
Autoloading, is likely to also become an issue, but I think you can declare autoload paths somehow (I don't know for sure, but googling "rails autoloading" gives some promising results, looks like it just hooks into Ruby's autoloading -- though I think this is going away in Ruby 2.0) worst case, you can probably define a railtie to eager load the dirs for you. This is all a bit out of my league, but I'd assume you need the railties defined before the app is initialized, so you may need to require the railtie in config/application.rb
Unfortunately, at the end of the day, when you start deviating from Rails conventions, life starts getting hard, and all that magic you never had to think about breaks down so you suddenly have to go diving into the Rails codebase to figure out what it was doing.
I'm interested in simply slowing down the evaluation of ruby code. Of course I know about using sleep(), but that does not solve my problem.
Rather, I want to slow down every single object instantiation and destruction that happens in the VM.
Why? So I can learn about how particular procedures in ruby work by watching them being carried out. I recently learned about ObjectSpace and the ability to see/inspect all the objects currently living in a Ruby VM. It seems that building a simple realtime display of the objects and properties of those objects within the ObjectSpace and then slowing down the evaluation would achieve this.
I realize there may be ways of viewing in realtime more detailed logs of what is happening inside the ruby process, including many procedures that are implemented at low-level, below the level of actual ruby code. But I think simply seeing the creation and destruction of objects and their properties in realtime would be more edifying and easier to follow.
You could be interested in the answer to this question: getting in-out from ruby methods
With small edits to the code reported there, you could add a sleep to each method call and follow the code execution.
If you want to output some information every time an object is instantiated, you could do that by overriding Class#new. Here's an example:
class Class
alias old_new new
def new(*args)
puts "Creating: #{self.inspect}"
sleep 0.1
old_new(*args)
end
end
class Point
end
class Circle
end
The alias old_new new line creates a backup new method, so we can have the old behaviour. Then, we override the new method and put some code to inspect the subject class and sleep for just a bit for the sake of better readability. Now, if you invoke Point.new, you'll see "Creating: Point". Circle.new will display a "Creating: Circle" and so on. Any objects that are created will be logged, or at least their classes, with a small delay.
The example is a modified version of the one from here.
As for destruction of objects, I'm not sure if there's a sensible way to do it. You could try to override some method in the GC module, but garbage collection is only initiated when it's necessary (as far as I'm aware), so you could easily play with ruby for a while without it ever happening. It probably wouldn't be very useful anyway.
I think the problem is not that ruby is too fast.
In your case you should use some software architecture, for example Model-View-Controller.
It could be in this way. In View you can show options at which speed the Controller should show information for you or you're able to slow down or increase the speed of showing information. Then Controller evaluate small steps (calling methods in Model) and rendered the results of evaluation in the View.
The View is not always the browser or window application, it could be also just a simple terminal.