Skip to content

magic4dev/systemdy

Repository files navigation

Systemdy Logo

Gem Gem GitHub forks GitHub issues GitHub license GitHub stars

Systemdy

A lightweight gem for interact with Systemd.

If your goal is to develop software to quickly manage systemd services or journalctl logs, this gem is for you! 😁

Features

  • Lightweight
  • Expressive classes and methods
  • Manage Systemd's services lifecycle with minimal effort!
  • Extract and manipulate Journalctl logs with a single action!

Table of contents

Installation

Add this line to your application's Gemfile:

gem 'systemdy'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install systemdy

Dependencies

The only dependecy you need is systemd installed on your system (specifically libsystemd or the older libsystemd-journal) in order to use the gem. Currently the gem support systemd 249 or higher.

Usage

After installing the gem, the first step is to require it:

require 'systemdy'

Manage services

The first goal of this gem is to manage a systemd's service with minimal effort.

This section provides an overview of the Systemdy::Service class for managing the life cycle of a systemd's service.

Create a Systemdy Service object for control a service

The first step is to create a new instance of the Systemdy::Service class for control the desired service

my_postgresql_service = Systemdy::Service.new('postgresql')

Check if the provided service exist

Once our object has been instantiated, you can check if the service is installed on your system

my_postgresql_service.exist?

For check if a service is installed on your system without create a new instance of the Systemdy::Service class

Systemdy::Utility::Validator.check_if_a_service_exist('postgresql')

if the provided service is installed on your system this methods return true, otherwise return false.

Check if the provided service is enabled

For check if a service is enabled

my_postgresql_service.is_enabled?

if the provided service is enabled this method return true, otherwise return false.

Check if the provided service is active

For check if a service is active

my_postgresql_service.is_active?

if the provided service is active this method return true, otherwise return false.

Check the current status of the provided service

For check the current status of the service

my_postgresql_service.status

Once executed, this method return an hash with all the essential service's information like this:

 { "Id"=>"postgresql.service",              
   "Description"=>"PostgreSQL RDBMS",          
   "ExecMainPID"=>"48615",
   "LoadState"=>"loaded",
   "ActiveState"=>"active",
   "FragmentPath"=>"/lib/systemd/system/postgresql.service",
   "ActiveEnterTimestamp"=>"Thu 2022-09-29 17:13:07 CEST",
   "InactiveEnterTimestamp"=>"Thu 2022-09-29 17:12:44 CEST",
   "ActiveExitTimestamp"=>"Thu 2022-09-29 17:12:44 CEST",
   "InactiveExitTimestamp"=>"Thu 2022-09-29 17:13:07 CEST"
 } 

Display all the properties for the provided service

For check all the properties of the service

my_postgresql_service.properties

Once executed, this method return an hash with all the service's properties like this:

 { "Type"=>"oneshot",
    "Restart"=>"no",
    "NotifyAccess"=>"none",
    ....
 }

To extract the value of a specific property

my_postgresql_service.properties["MemorySwapMax"]

Get service port

For retrieve a service port

my_postgresql_service.port

Once executed, this method return the provided service port:

 "5432"

if the provided service has no available port, this method return a message like this:

 "[name_of_the_service].service has no port available"

Get service protocol

For retrieve a service protocol

my_postgresql_service.protocol

Once executed, this method return the provided service protocol:

  "tcp"

if the provided service has no available protocol, this method return a message like this:

 "[name_of_the_service].service has no protocol available"

Start the service

For start the service

my_postgresql_service.start

Restart the service

For restart the service

my_postgresql_service.restart

Stop the service

For stop the service

my_postgresql_service.stop

Enable the service

For enable the service

my_postgresql_service.enable

Disable the service

For disable the service

my_postgresql_service.disable

Reload the service

For reload the service

my_postgresql_service.reload

Mask the service

For mask the service

my_postgresql_service.mask

Unmask the service

For unmask the service

my_postgresql_service.unmask

Bonus tip: execute systemctl commands without prompt the password

The methods start, restart, stop, enable, disable, reload, mask and unmask detect non-root users and automatically execute the methods with sudo.

By default, sudo needs that a non-root user(in this case you) is authenticated using a password for complete the method execution. This is a great thing, but some times you may need to execute this methods without type the password.

In this case you need to configure sudo without a password.

The first step for achieve this is gain root access:

non_root_user@my-machine:~$ sudo -i
[sudo] password for non_root_user: 

After provided the correct password backup your /etc/sudoers file by typing the following command:

root@my-machine:~# cp /etc/sudoers /root/sudoers.bak 

Next step is edit the /etc/sudoers file by typing the visudo command:

root@my-machine:~# visudo 

Append/edit the following lines in the /etc/sudoers file and substitute 'your_account_name' with your linux account name.

'your_account_name' ALL=(ALL) NOPASSWD: /bin/systemctl

This line anable you to run ‘systemctl’ commands without a password.

Save with CTRL + X

Type 'exit' on your terminal as follows:

root@my-machine:~# exit

Exit from root session and you are ready to go! 😎

Manage Journalctl logs

The second goal of this gem is to provide a set of useful methods for retrieving journalctl log data.

This section provides a brief overview of the Systemdy::Journal class for managing journalctl log information.

Display kernel logs

Sometimes we need to check if the kernel is working properly or if something went wrong to get useful information to help us fix the problem.

For getting the kernel logs

Systemdy::Journal.display_kernel_logs

This class method executed with no arguments return an array with:

  • a default size of 10 (the last 10 lines of log)
  • a start period not older than '00:00 AM' o' clock (today)
  • an end period not newer than the method execution timenow

Obviously this method allows you to filter the kernel logs by passing 3 positional arguments:

  • since: a start period not older than the specified date

  • to: an end period not older than the specified date

  • lines: the exact number of last log lines

For example:

If you want to analyze the last 50 log lines ranging from a month ago to 10:00 of the current day:

Systemdy::Journal.display_kernel_logs(since: '1 month ago', to: '10:00', lines: 50)

If you want to analyze the last 20 log lines ranging from a week ago to yesterday:

Systemdy::Journal.display_kernel_logs(since: '1 week ago', to: 'yesterday', lines: 20)

You can also filter the logs by specific dates in the format YYYY-MM-DD for example:

Systemdy::Journal.display_kernel_logs(since: '2022-08-27', lines: 200)

If the passed arguments not match anything the method return an array with a message like this:

["-- No entries --"]

Display boot logs

Sometimes we need to know if our system is working properly at boot time and if something went wrong to get useful information to help us fix the problem.

For getting the boot logs

Systemdy::Journal.display_boot_logs

This class method executed with no arguments return an array with:

  • a default size of 10 (the last 10 lines of log)
  • a start period not older than '00:00 AM' o' clock (today)
  • an end period not newer than the method execution timenow

Obviously as for the previous method, you can filter the boot logs by passing 4 positional arguments:

  • argument: in this case the boot's number

  • since: a start period not older than the specified date

  • to: an end period not older than the specified date

  • lines: the exact number of last log lines

For example:

If you want to analyze the last 50 log lines of the second boot ranging from a month ago to 10:00 of the current day:

Systemdy::Journal.display_boot_logs(argument: 2, since: '1 month ago', to: '10:00', lines: 50)

If you want to analyze the last 20 log of the third boot lines ranging from a week ago to yesterday:

Systemdy::Journal.display_boot_logs(argument: 3, since: '1 week ago', to: 'yesterday', lines: 20)

You can also filter the logs by specific dates in the format YYYY-MM-DD for example:

Systemdy::Journal.display_boot_logs(since: '2022-08-27', lines: 200)

If the passed arguments not match anything the method return an array with a message like this:

["-- No entries --"]

Display unit logs

Another common task is to filter logs based on the unit that we need information on.

To do this, we just simply need to pass the name of the unit as argument, for example we need to analyze postgresql unit logs:

Systemdy::Journal.display_unit_logs(argument: 'postgresql')

In this case the class method return an array with:

  • a default size of 10 (the last 10 lines of log)
  • a start period not older than '00:00 AM' o' clock (today)
  • an end period not newer than the method execution timenow

Obviously this method require the unit's name as argument, if executed with no arguments return a message like this:

"display_unit_logs require an argument!"

As for the previous method, you can filter the unit logs by passing 4 positional arguments:

  • argument: in this case the unit's name

  • since: a start period not older than the specified date

  • to: an end period not older than the specified date

  • lines: the exact number of last log lines

For example:

If you want to analyze the last 50 log lines of the potsgresql service ranging from a month ago to 10:00 of the current day:

Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '1 month ago', to: '10:00', lines: 50)

If you want to analyze the last 20 log lines of the potsgresql service ranging from a week ago to yesterday:

Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '1 week ago', to: 'yesterday', lines: 20)

You can also filter the logs by specific dates in the format YYYY-MM-DD for example:

Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '2022-08-27', lines: 200)

If the passed arguments not match anything the method return an array with a message like this:

["-- No entries --"]

Display group_id logs (GUID)

To find all messages related to a particular group, we just simply need to pass the GUID of the group as argument, for example:

Systemdy::Journal.display_group_id_logs(argument: 1000)

In this case the class method return an array with:

  • a default size of 10 (the last 10 lines of log)
  • a start period not older than '00:00 AM' o' clock (today)
  • an end period not newer than the method execution timenow

Obviously this method require the GUID as argument, if executed with no arguments return a message like this:

"display_group_id_logs require an argument!"

As for the previous method, you can filter the GUID logs by passing 4 positional arguments:

  • argument: in this case the GUID

  • since: a start period not older than the specified date

  • to: an end period not older than the specified date

  • lines: the exact number of last log lines

For example:

If you want to analyze the last 50 log lines of the GUID 1000 ranging from a month ago to 10:00 of the current day:

Systemdy::Journal.display_group_id_logs(argument: 1000, since: '1 month ago', to: '10:00', lines: 50)

If you want to analyze the last 20 log lines of the GUID 1000 ranging from a week ago to yesterday:

Systemdy::Journal.display_group_id_logs(argument: 1000, since: '1 week ago', to: 'yesterday', lines: 20)

You can also filter the logs by specific dates in the format YYYY-MM-DD for example:

Systemdy::Journal.display_group_id_logs(argument: 1000, since: '2022-08-27', lines: 200)

If the passed arguments not match anything the method return an array with a message like this:

["-- No entries --"]

Display user_id logs (UID)

To find all messages related to a particular user, we just simply need to pass the UID of the user as argument, for example:

Systemdy::Journal.display_user_id_logs(argument: 1000)

In this case the class method return an array with:

  • a default size of 10 (the last 10 lines of log)
  • a start period not older than '00:00 AM' o' clock (today)
  • an end period not newer than the method execution timenow

Obviously this method require the UID as argument, if executed with no arguments return a message like this:

"display_user_id_logs require an argument!"

As for the previous method, you can filter the UID logs by passing 4 positional arguments:

  • argument: in this case the UID

  • since: a start period not older than the specified date

  • to: an end period not older than the specified date

  • lines: the exact number of last log lines

For example:

If you want to analyze the last 50 log lines of the UID 1000 ranging from a month ago to 10:00 of the current day:

Systemdy::Journal.display_user_id_logs(argument: 1000, since: '1 month ago', to: '10:00', lines: 50)

If you want to analyze the last 20 log lines of the UID 1000 ranging from a week ago to yesterday:

Systemdy::Journal.display_user_id_logs(argument: 1000, since: '1 week ago', to: 'yesterday', lines: 20)

You can also filter the logs by specific dates in the format YYYY-MM-DD for example:

Systemdy::Journal.display_user_id_logs(argument: 1000, since: '2022-08-27', lines: 200)

If the passed arguments not match anything the method return an array with a message like this:

["-- No entries --"]

Contributing

We ❤️ pull requests from everyone.

Everyone interacting in the systemdy's project codebase is expected to follow the code of conduct.

Develop a new feature

If you wanna develop a new feature:

  • Fork this project

  • Clone the repo with the following command:

    git clone [email protected]:your-username/systemdy.git
    
  • Install dependencies with:

    bin/setup
    
  • Make your changes

  • Write tests.

    NOTE: For a correct testing procedure read our Note for testing

  • Make the tests pass with the following command:

    rake spec
    
  • Add notes about your changes to the CHANGELOG.md file

  • Write a good commit message

  • Push to your fork

  • Submit a pull request

  • Wait for us, we will reply as soon as possible and if is the case we suggest some changes for a better quality of the code

  • Please, if you push more than one commit let's keep the history clean 😜

Thank you for your contribution! 🤝

Fix a bug

If you wanna fix a bug:

  • Fork this project

  • Clone the repo with the following command:

    git clone [email protected]:your-username/systemdy.git
    
  • Install dependencies with:

    bin/setup
    
  • Make your changes

  • Write tests.

    NOTE: For a correct testing procedure read our Note for testing

  • Make the tests pass with the following command:

    rake spec
    
  • Add notes about your changes to the CHANGELOG.md file

  • Write a good commit message

  • Push to your fork

  • Submit a pull request

  • Wait for us, we will reply as soon as possible and if is the case we suggest some changes for a better quality of the code

  • Please, if you push more than one commit let's keep the history clean 😜

Thank you for your contribution! 🤝

Note for testing

This gem was tested on a postgresql service.

For better testing install postgresql service on your system.

If you don't want to install it:

  • go to spec/setup/test_variables.rb

and replace:

  • let (:real_service_name) { 'postgresql' }

with a service already installed on your system as follows:

  • let (:real_service_name) { 'a_service_already_installed_on_your_system' }

License

The gem is available as open source under the terms of the MIT License.

Useful links and resources

Acknowledgements

About

No description, website, or topics provided.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published