Rotacja dzienników produkcji Ruby on Rails

172

Jaki jest najlepszy sposób na włączenie rotacji logów w aplikacji produkcyjnej Ruby on Rails?

Czy odbywa się to za pomocą logrotate na serwerze hostingowym, czy też istnieje zestaw opcji do użycia podczas inicjowania rejestratora z aplikacji?

cnicolaou
źródło
Widzę, że jest już odpowiedź na to pytanie, ale chciałem zapytać, jakie jest Twoje środowisko. Sam korzystam z metody syslog + logrotate, ale oczywiście rodzaj środowiska (dedykowane, współdzielone, jakiego typu * ix OS hostuje, czy jest inne, itp.) Miałby tutaj znaczenie.
ylluminate

Odpowiedzi:

203

Opcja 1: syslog + logrotate

Możesz skonfigurować szyny, aby używać narzędzi dziennika systemowego.

Przykład w config / environment / production.rb .

# Use a different logger for distributed setups
config.logger = SyslogLogger.new

W ten sposób logujesz się do syslog i możesz używać domyślnych narzędzi logrotate do obracania dzienników.

Opcja 2: normalne logi Railsów + logrotate

Inną opcją jest po prostu skonfigurowanie logrotate do zbierania kłód pozostawionych przez szyny. W systemach Ubuntu i Debian będzie to na przykład plik o nazwie /etc/logrotate.d/rails_example_com.

/path/to/rails.example.com/tmp/log/*.log {
    weekly
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    copytruncate
}

Zgodnie z poniższymi sugestiami, w Railsach zaleca się użycie copytruncate, aby uniknąć konieczności ponownego uruchamiania aplikacji Rails.

Edycja: usunięto "sharedscripts / endcript", ponieważ nie są one tutaj używane i powodują problemy zgodnie z komentarzem. I usunięte create 640 root admzgodnie z sugestią komentarza.

Berkes
źródło
3
Aby użyć logrotate, czy wiersz "config.logger = SyslogLogger.new" w config / environment / production.rb powinien pozostać zakomentowany, czy też powinien być odkomentowany?
robertwbradford
2
Powinien pozostać zakomentowany, aby pliki dziennika były zapisywane (na przykład): /var/www/myrailsapp/current/log/production.log
Luca Spiller
3
Jeśli korzystasz z logrotaterozwiązania, warto odpowiedzieć @ amit-saxena - sugeruje użycie copytruncateponad createdyrektywy.
Tom Harrison,
3
Kiedy używasz copytruncate, createnie ma efektu, więc prawdopodobnie powinieneś usunąć go ze swojego przykładu
Michaël Witrant
3
Być może będziesz musiał dodać wiersz su your_rails_user your_rails_groupz właścicielem i grupą twoich plików dziennika (tj. Tych z procesu Rails / Passenger) lub (ostatnie wersje?) Logrotate może narzekać na uprawnienia.
oseiskar
56

Jeśli używasz logrotate, możesz wybrać jedną z poniższych opcji, umieszczając plik conf w katalogu /etc/logrotate.d/.

# Rotate Rails application logs based on file size
# Rotate log if file greater than 20 MB
/path/to/your/rails/applicaton/log/*.log {
    size=20M
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    copytruncate
}

Lub

# Rotate Rails application logs weekly
/path/to/your/rails/applicaton/log/*.log {
  weekly
  missingok
  rotate 52
  compress
  delaycompress
  notifempty
  copytruncate
}

Należy pamiętać, że copytruncate tworzy kopię zapasową bieżącego dziennika, a następnie czyści plik dziennika w celu kontynuowania zapisu. Alternatywą jest użycie funkcji create, która wykona obrót przez zmianę nazwy bieżącego pliku, a następnie utworzenie nowego pliku dziennika o tej samej nazwie co stary plik. Zdecydowanie zalecam używanie copytruncate, chyba że wiesz, że potrzebujesz utworzyć. Powodem jest to, że Railsy mogą nadal wskazywać na stary plik dziennika, mimo że jego nazwa uległa zmianie i mogą wymagać ponownego uruchomienia w celu zlokalizowania nowego pliku dziennika. copytruncate pozwala uniknąć tego, zachowując ten sam plik, co plik aktywny.

amit_saxena
źródło
Ale czy nie powinienem restartować railsów za każdym razem, gdy uruchomi się logrotate?
lzap
2
Skróć oryginalny plik dziennika w miejscu po utworzeniu kopii, zamiast przenosić stary plik dziennika i opcjonalnie tworzyć nowy.Można go użyć, gdy nie można nakazać niektórym programom, aby zamknęły swój plik dziennika i dlatego mogą kontynuować zapisywanie (dołączanie) do poprzedni plik dziennika na zawsze. Zwróć uwagę, że między skopiowaniem pliku a jego obcięciem jest bardzo krótki okres czasu, więc niektóre dane logowania mogą zostać utracone. Gdy ta opcja jest używana, opcja tworzenia nie odniesie żadnego skutku, ponieważ stary plik dziennika pozostaje na swoim miejscu.
lzap
1
Nie musisz ponownie uruchamiać rails, jeśli używasz copytruncate, ponieważ nadal wskazuje na ten sam plik dziennika.
amit_saxena
Czy konfiguracja wymaga określenia, kiedy należy obrócić dzienniki? na przykład „co tydzień” lub „rozmiar = 20 mln”? A może możesz to pominąć, jeśli chcesz uruchomić logrotate tylko ręcznie?
Damainman,
1
Nie jestem pewien, czy dobrze zrozumiałem Twoje pytanie, ale musisz określić kryterium automatycznej rotacji dzienników. Jeśli nie chcesz, aby było to automatyczne, nie umieszczaj pliku w katalogu /etc/logrotate.d/, przechowuj go w innym miejscu. Następnie można uruchomić logrotate --force $CONFIG_FILE, określając lokalizację pliku konfiguracyjnego, aby uruchomić go ręcznie.
amit_saxena
31

W przypadku Rails 5 musiałem to zrobić, aby ograniczyć rozmiar dziennika i nie zmieniać wyjścia serwera w konsoli:

Zgodnie z dokumentacją , jeśli chcesz ograniczyć rozmiar folderu dziennika, umieść to w pliku środowiska („development.rb” / „production.rb”).

config.logger = ActiveSupport::Logger.new(config.paths['log'].first, 1, 50 * 1024 * 1024)

Dzięki temu Twoje pliki dziennika nigdy nie będą większe niż 50 MB. Możesz zmienić rozmiar według własnych preferencji. Wartość „1” w drugim parametrze oznacza, że ​​zostanie zachowany 1 plik dziennika, więc będziesz mieć do 100 MB dzienników - bieżący dziennik i poprzedni fragment o wielkości 50 MB.

Źródło tego rozwiązania .

Kolega nieznajomy
źródło
2
Pierwszy argument to nazwa pliku, mówiąc najprościej, tj. „Log / development.log”. Więc wolałbym dłuższy, ale przejrzysty sposób. Zamiast config.paths['log'].firstbym umieścićRails.root.join('log', "#{Rails.env}.log")
Michaił Chuprynski
1
@ZiaUlRehmanMughal Tak, działa z Railsami 4. Używam Rails 4.2.3, z taką konfiguracją: config.logger = ActiveSupport::Logger.new(config.log_file, 1, 20*1024*1024)
ThienSuBS
1
Aby ułatwić czytanie, warto wspomnieć, że możesz polegać na rozszerzeniach bajtów ActiveSupport: 50.megabytesjest takie samo 50 * 1024 * 1024, ale znacznie łatwiejsze do zrozumienia. Aby uzyskać więcej informacji, zobacz podstawowe rozszerzenia ActiveSupport .
Pierre-Adrien Buisson
1
Znów tu dotarłem po googlowaniu (życie programisty: D). Zastanawiałem się, czy możemy skonfigurować tę linię tak, aby obracała wszystkie pliki dziennika w folderze dziennika? Najwyraźniej ta linia będzie obracać tylko pierwszą linię.
Zia Ul Rehman Mughal
Zauważ, że spowoduje to tylko obrócenie pliku log / production.log, ponieważ Rails.application.config.paths['log'].firstzwróci dokładnie ten plik
valachi
5

W przypadku Rails 5 , jeśli chcesz mieć codzienną rotację dzienników, potrzebujesz tylko tego:

  config.logger = ActiveSupport::Logger.new(config.paths['log'].first, shift_age = 'daily')

Zgodnie z dokumentacją , można użyć daily, weeklylub monthly.

Rael Gugelmin Cunha
źródło
2

Dla każdego logu: Rails log, Rpush log, ... Możesz użyć tego w swoim pliku konfiguracyjnym usługi:

 config.log_file = 'log/rpush.log'
 config.logger = ActiveSupport::Logger.new(config.log_file, 1, 20*1024*1024)

Oznacza to: po podziale zapisz tylko 1 poprzedni plik dziennika. Rozmiar głównego dziennika nigdy nie przekracza 20 MB.

ThienSuBS
źródło
-9

Włącz wysyłanie dzienników do loggly przy użyciu logglier rails, jak pokazano w moim pliku environment / production.rb. wersja railsów to 4.1.0

RailsApplication::Application.configure do
require 'logglier'
config.logger = Logglier.new(<https://logs-01.loggly.com/inputs/inputkey>)
log.info("hello from logglier")
end
riya khana
źródło
Proszę zasugeruj mi coś, co mam zrobić ... ten kod nie działa
riya khana
Wersja Railsów to 4.1.0, a Ruby to 2.1.1
riya khana