<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://rajarshig.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://rajarshig.github.io/" rel="alternate" type="text/html" /><updated>2026-04-12T10:24:14+00:00</updated><id>https://rajarshig.github.io/feed.xml</id><title type="html">Posts about learnings, development tips &amp;amp; much more!</title><subtitle>A blog featuring posts on DevOps, AWS, Python, and other development topics</subtitle><author><name>Rajarshi Ghosh</name></author><entry><title type="html">How Covid surge in India affects the global vaccine supply</title><link href="https://rajarshig.github.io/posts/how-covid-surge-in-india-affects-the-global-vaccine-supply/" rel="alternate" type="text/html" title="How Covid surge in India affects the global vaccine supply" /><published>2021-05-16T00:00:00+00:00</published><updated>2021-05-16T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/how-covid-surge-in-india-affects-the-global-vaccine-supply</id><content type="html" xml:base="https://rajarshig.github.io/posts/how-covid-surge-in-india-affects-the-global-vaccine-supply/"><![CDATA[<p>India is one of the major producers of vaccines for global usage. Around the year 2020, WHO envisaged a plan to provide sufficient Covid-19 vaccines to selected lower-income countries.
A majority of vaccines for this plan were to be produced in indian companies. However, around early 2021, a sudden surge of local covid cases in India pushed the local demand for vaccination.
This led the Indian government to temporarily restrict vaccine export which jeopardised the global vaccine distribution plan. In turn, this event puts pressure on developed countries to open up vaccine exports.</p>

<p>As per recommendations of global researchers, early vaccination for majority of the global population is the only way to restrict the mutations of Covid vaccines. The longers people remain unvaccinated, the higher the chances of new &amp; possibly deadlier variants appearing by mutation.
What is even more concerning is the fact that there is not enough knowledge or confidence in the medical community about how useful the current vaccines will be against new variants.</p>

<p>So in summary, the global race to contain Covid &amp; its variants are not very encouraging. One can only that the global leaders &amp; agencies get together to plan &amp; execute the vaccination drive in the most timely &amp; efficient manner in the coming days.</p>]]></content><author><name>Rajarshi Ghosh</name></author><summary type="html"><![CDATA[India is one of the major producers of vaccines for global usage. Around the year 2020, WHO envisaged a plan to provide sufficient Covid-19 vaccines to selected lower-income countries. A majority of vaccines for this plan were to be produced in indian companies. However, around early 2021, a sudden surge of local covid cases in India pushed the local demand for vaccination. This led the Indian government to temporarily restrict vaccine export which jeopardised the global vaccine distribution plan. In turn, this event puts pressure on developed countries to open up vaccine exports.]]></summary></entry><entry><title type="html">Setup Cron job in Ubuntu 18.04</title><link href="https://rajarshig.github.io/posts/setup-cron-job-in-ubuntu-18-04/" rel="alternate" type="text/html" title="Setup Cron job in Ubuntu 18.04" /><published>2020-05-17T00:00:00+00:00</published><updated>2020-05-17T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/setup-cron-job-in-ubuntu-18-04</id><content type="html" xml:base="https://rajarshig.github.io/posts/setup-cron-job-in-ubuntu-18-04/"><![CDATA[<p>Cron is a tool for time based job scheduling - found in most of Unix based operating systems. Although it was developed long time ago, its simplicity &amp; effectiveness is remarkable.</p>

<h2 id="use">Use</h2>
<p>Any script or command which is to be executed in some time interval, can be set with Cron.</p>

<h2 id="points-to-remember">Points to remember</h2>
<ul>
  <li>Absolute paths for script or files need to be provided. For eg. I have a python file in a virtual environment which I want to set with Cron. In that case, I have to provide the command as below</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/home/username/venv/bin/python  /home/username/venv/project/script.py
</code></pre></div></div>
<ul>
  <li>It need to be planned if the output of the command (if any) need to be saved. It is also possible to setup email integration with a Cron job.</li>
</ul>

<h2 id="steps">Steps</h2>
<ul>
  <li>Below command opens the crontab file for current user. At the bottom, we can add multiple cron entries
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e
</code></pre></div>    </div>
  </li>
  <li>A single cron entry follows <code class="language-plaintext highlighter-rouge">m h dom mon dow</code> format, which means <code class="language-plaintext highlighter-rouge">minute hour dayofmonth month dayofweek command</code>. Detail instruction &amp; example are also included in the file itself</li>
  <li>To run a python script on 12PM daily, we would add below entry
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 12 * * * /home/username/venv/bin/python  /home/username/venv/project/script.py
</code></pre></div>    </div>
  </li>
  <li>To ignore a field, use <code class="language-plaintext highlighter-rouge">*</code>. Then only the non <code class="language-plaintext highlighter-rouge">*</code> fields will be considered, as here I have ignored the dom, mon, dow fields, so the Cron will run daily</li>
  <li>As the minimum time field is minute, we can not use seconds for Cron</li>
  <li>After entering the entry, use <code class="language-plaintext highlighter-rouge">Ctrl+O</code> &amp; <code class="language-plaintext highlighter-rouge">Ctrl+X</code> to save</li>
  <li>
    <p>Ensure there are no <code class="language-plaintext highlighter-rouge">\n</code> character in the entry line, else parsing error will be thrown while saving</p>
  </li>
  <li>The Cron <code class="language-plaintext highlighter-rouge">dameon</code> will check the entries in its own, so not need to restart it after entry</li>
  <li>The generated crontab file can be seen at <code class="language-plaintext highlighter-rouge">/var/spool/cron/crontabs/username</code></li>
  <li>The log of the Cron job can be found in <code class="language-plaintext highlighter-rouge">syslog</code>. We can search Cron logs by username
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat /var/log/syslog | grep "CRON" | grep "username"
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="conclusion">Conclusion</h2>
<ul>
  <li>Although Cron has its limitation, it provides a very stable way to automate administrative tasks</li>
  <li>It provides many more features &amp; options for various use cases</li>
</ul>

<h2 id="references">References:</h2>
<ul>
  <li><a href="https://www.digitalocean.com/community/tutorials/how-to-use-cron-to-automate-tasks-ubuntu-1804">https://www.digitalocean.com/community/tutorials/how-to-use-cron-to-automate-tasks-ubuntu-1804</a></li>
  <li><a href="https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/">https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/</a></li>
</ul>]]></content><author><name>Rajarshi Ghosh</name></author><category term="devops" /><summary type="html"><![CDATA[Cron is a tool for time based job scheduling - found in most of Unix based operating systems. Although it was developed long time ago, its simplicity &amp; effectiveness is remarkable.]]></summary></entry><entry><title type="html">Install PhpMyAdmin with Nginx on Ubuntu 18.04</title><link href="https://rajarshig.github.io/posts/install-phpmyadmin-with-nginx-on-ubuntu-18-04/" rel="alternate" type="text/html" title="Install PhpMyAdmin with Nginx on Ubuntu 18.04" /><published>2020-04-20T00:00:00+00:00</published><updated>2020-04-20T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/install-phpmyadmin-with-nginx-on-ubuntu-18-04</id><content type="html" xml:base="https://rajarshig.github.io/posts/install-phpmyadmin-with-nginx-on-ubuntu-18-04/"><![CDATA[<p>PhpMyAdmin is the most popular web interface for MySql whereas nginx is becoming a popular choice for web server. Here we will be going thourgh the process of setup a PhpMyAdmin instance with Nginx, in an Ubuntu 18.04 server. The steps may vary slightly for other ubuntu versions.</p>

<h2 id="setup-phpmyadmin">Setup PhpMyAdmin</h2>
<ul>
  <li>We are assuming php, mysql, nginx are already installed in the Ubuntu system</li>
  <li>Install PhpMyAdmin
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install phpmyadmin
</code></pre></div>    </div>
  </li>
  <li>During installation, below screen will appear &amp; ask to choose web server
<img src="images/phpmyadmin_web_server_prompt.png" alt="hi" class="inline" /></li>
</ul>

<p>As we will be using Nginx as web server, don’t select any of the options &amp; enter “Ok”</p>
<ul>
  <li>In next steps, a new database user for PhpMyAdmin will be created &amp; a database named ‘phpmyadmin’ will be created as well</li>
  <li>After successful installation, phpmyadmin folder can be found at <code class="language-plaintext highlighter-rouge">/usr/share/phpmyadmin</code>. We will create a symlink to <code class="language-plaintext highlighter-rouge">/var/www/html</code> using following command
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="create-nginx-server-block">Create Nginx Server Block</h2>
<ul>
  <li>Create a server block file for phpmyadmin at <code class="language-plaintext highlighter-rouge">/nginx/sites-available/phpmyadmin</code> &amp; put below content
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
      root /var/www/html;

      # Add index.php to the list if you are using PHP
      index index.php index.html index.htm index.nginx-debian.html;

      server_name ***.**.***.*;

      location ~ \.php$ {
         include snippets/fastcgi-php.conf;
         fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include fastcgi_params;
     }
}
</code></pre></div>    </div>
  </li>
  <li>Test nginx configuration by running <code class="language-plaintext highlighter-rouge">sudo nginx -t</code>. If no error found, restart nginx by <code class="language-plaintext highlighter-rouge">sudo service restart nginx</code></li>
  <li>The phpmyadmin web interface will be available at <code class="language-plaintext highlighter-rouge">[Your_IP]/phpmyadmin</code> web address</li>
</ul>

<h3 id="change-name-of-phpmyadmin-folder-for-security">Change name of PhpMyAdmin folder for security</h3>
<ul>
  <li>As automated hacking attack can target the url [IP]/phpmyadmin, it is better practice to use some other name instead of phpmyadmin in the web link.</li>
  <li>To do this, simply change the folder name in <code class="language-plaintext highlighter-rouge">/var/www/html</code> by command <code class="language-plaintext highlighter-rouge">sudo mv phpmyadmin mydb</code></li>
  <li>After that the interface will be available at <code class="language-plaintext highlighter-rouge">[Your_IP/mydb]</code> web address</li>
</ul>

<h2 id="footnote">Footnote</h2>
<ul>
  <li>There are many more steps regarding setup of Phpmyadmin with mysql &amp; nginx, related to security &amp; best practices. Please follow those as seem fit.</li>
</ul>]]></content><author><name>Rajarshi Ghosh</name></author><category term="devops" /><summary type="html"><![CDATA[PhpMyAdmin is the most popular web interface for MySql whereas nginx is becoming a popular choice for web server. Here we will be going thourgh the process of setup a PhpMyAdmin instance with Nginx, in an Ubuntu 18.04 server. The steps may vary slightly for other ubuntu versions.]]></summary></entry><entry><title type="html">AWS S3 usage with Python &amp;amp; Boto3 library</title><link href="https://rajarshig.github.io/posts/aws-s3-usage-with-python-and-boto3-library/" rel="alternate" type="text/html" title="AWS S3 usage with Python &amp;amp; Boto3 library" /><published>2020-02-10T00:00:00+00:00</published><updated>2020-02-10T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/aws-s3-usage-with-python-and-boto3-library</id><content type="html" xml:base="https://rajarshig.github.io/posts/aws-s3-usage-with-python-and-boto3-library/"><![CDATA[<p>Cloud based object storage has become an important part of any software application stack in recent times. <a href="https://aws.amazon.com/s3/">AWS S3</a> has become the de-facto choice for this use case.</p>

<h2 id="use-with-python">Use with python</h2>
<ul>
  <li>The official sdk for python is <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/index.html">Boto3</a> which provide API for using AWS S3.</li>
</ul>

<h3 id="create-boto3-configuration-using-aws-credentials">Create boto3 configuration using AWS credentials</h3>
<ul>
  <li>Below is an example of basic boto3 configuration. More details, options &amp; best practices can be found in <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html">https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html</a></li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import boto3

s3_resource = boto3.resource(
    "s3",
    aws_access_key_id="**********",
    aws_secret_access_key="**********",
)
</code></pre></div></div>
<h2 id="s3-file-download">S3 File download</h2>

<h3 id="get-file-objects-of-a-bucket">Get file objects of a Bucket</h3>
<ul>
  <li>Set <code class="language-plaintext highlighter-rouge">bucket</code> variable as name of the S3 bucket</li>
  <li>Set <code class="language-plaintext highlighter-rouge">prefix</code> variable as name of S3 folder structure prefix. For eg. for file name like <code class="language-plaintext highlighter-rouge">s3://bucketname/[clientid]/file1.csv</code>, clientid can be used as prefix to get only files starting with a particular clientid.</li>
  <li>Using the above, we can use the <code class="language-plaintext highlighter-rouge">list_objects_v2</code> method to get a list of matching file objects
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>obj = s3_resource.meta.client.list_objects_v2(Bucket=bucket, Prefix=prefix)
all_keys_obj = obj['Contents']
</code></pre></div>    </div>
  </li>
  <li>The output of the above step is a list of s3 objects, like below
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[
  {'Key': '*****', 'LastModified': datetime.datetime(2020, 3, 3, 12, 16, 16, tzinfo=tzutc()), 'ETag': '"*****"', 'Size': 869061, 'StorageClass': 'STANDARD', 'Owner': {'ID': '*****'}},
  ....
  {'Key': '*****', 'LastModified': datetime.datetime(2020, 3, 3, 12, 18, 10, tzinfo=tzutc()), 'ETag': '"*****"', 'Size': 23333915, 'StorageClass': 'STANDARD', 'Owner': {'ID': '*****'}}
]
</code></pre></div>    </div>
  </li>
</ul>]]></content><author><name>Rajarshi Ghosh</name></author><category term="aws" /><category term="python" /><summary type="html"><![CDATA[Cloud based object storage has become an important part of any software application stack in recent times. AWS S3 has become the de-facto choice for this use case.]]></summary></entry><entry><title type="html">Python logging in JSON format</title><link href="https://rajarshig.github.io/posts/python-logging-in-json-format/" rel="alternate" type="text/html" title="Python logging in JSON format" /><published>2020-02-08T00:00:00+00:00</published><updated>2020-02-08T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/python-logging-in-json-format</id><content type="html" xml:base="https://rajarshig.github.io/posts/python-logging-in-json-format/"><![CDATA[<p>Logging in python can be achieved using inbuilt <code class="language-plaintext highlighter-rouge">logging</code> module. However, analysing the text based logs like below, can be complicated for log aggregation tools like ELK, especially in a microservice architecture</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2020-07-20 12:05:30,766 - __main__ - DEBUG - This is a debug message
</code></pre></div></div>
<p>Alternatively, if we manage to output logs as stream of json objects with pre-defined key-values, it becomes much easier to index &amp; analyse in an organised manner.</p>

<h2 id="required-package">Required package</h2>
<p>One such python package, which enabled Json logging for python application is <a href="https://github.com/thangbn/json-logging-python">https://github.com/thangbn/json-logging-python</a>. Other similar solutions are also available.</p>

<h2 id="install">Install</h2>
<ul>
  <li>Using <code class="language-plaintext highlighter-rouge">pip</code>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip install json-logging
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="example-setup">Example setup</h2>
<ul>
  <li>Create a genetic utility function to return a <code class="language-plaintext highlighter-rouge">logger</code> object</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def get_logger():
    """
    Generic utility function to get logger object with fixed configurations
    :return:
    logger object
    """
    json_logging.ENABLE_JSON_LOGGING = True
    json_logging.init_non_web()
    logger = logging.getLogger(__name__)
    logging.basicConfig()
    json_logging.config_root_logger()
    logger.setLevel(logging.DEBUG)
    logging.addLevelName(logging.ERROR, 'error')
    logging.addLevelName(logging.WARNING, 'warning')
    logging.addLevelName(logging.INFO, 'info')
    logging.addLevelName(logging.DEBUG, 'debug')
    logger.addHandler(logging.NullHandler())
    return logger

</code></pre></div></div>
<ul>
  <li>Create a <code class="language-plaintext highlighter-rouge">logger</code> object
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>logger = get_logger()
</code></pre></div>    </div>
  </li>
  <li>Sample log generation code &amp; output</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>logger.error(e)
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{"written_at": "2020-08-01T19:39:45.359Z", "written_ts": 1596310785359963000, "msg": "Internal Server Error: /api/endpoint1/user_name", "type": "log", "logger": "django.request", "thread": "Thread-3", "level": "error", "module": "log", "line_no": 228, "exc_info": "Traceback (most recent call last):\n...", "filename": "log.py"}

</code></pre></div></div>

<h2 id="ideas-for-advanced-use">Ideas for advanced use</h2>
<ul>
  <li>In addition to general logs, we can also use log messages with custom key-values for specific insights about the application. For example, we can add some extra keys to keep track of inter-api response time &amp; use it afterwards to understand application performance.</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>logger.info("Fetched from apiA/search",
                       extra={'props':
                           {
                               'caller_api': 'apiA',
                               'receiver_api': 'apiB',
                               'receiver_endpoint': 'search',
                               'api_response_parsed_duration': 28
                           }
                       }
            )

</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>
<p>As json is one of the most flexible, portable &amp; understandable data transfer format, it can provide immense benefit to use json logging for any application (including python).</p>]]></content><author><name>Rajarshi Ghosh</name></author><category term="python" /><summary type="html"><![CDATA[Logging in python can be achieved using inbuilt logging module. However, analysing the text based logs like below, can be complicated for log aggregation tools like ELK, especially in a microservice architecture 2020-07-20 12:05:30,766 - __main__ - DEBUG - This is a debug message Alternatively, if we manage to output logs as stream of json objects with pre-defined key-values, it becomes much easier to index &amp; analyse in an organised manner.]]></summary></entry><entry><title type="html">Python logging — a basic implementation</title><link href="https://rajarshig.github.io/posts/python-logging-basic-implementation/" rel="alternate" type="text/html" title="Python logging — a basic implementation" /><published>2019-11-06T00:00:00+00:00</published><updated>2019-11-06T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/python-logging-basic-implementation</id><content type="html" xml:base="https://rajarshig.github.io/posts/python-logging-basic-implementation/"><![CDATA[<h2 id="introduction">Introduction</h2>

<p>Generating appropriate log is a primary necessity in a software application. The main benefits of a well configured log output in comparison of print statements are such as -</p>

<ol>
  <li>
    <p>Provides diagnostic details like module name, line number, traceback, loglevel etc</p>
  </li>
  <li>
    <p>Log stream can be directed to various output like file, central logging system, container log etc</p>
  </li>
  <li>
    <p>Loglevel can be modified to control the log output, without modifying code &amp; restarting application.</p>
  </li>
</ol>

<h2 id="python-configuration">Python Configuration</h2>

<p>Below code create a basic logging configuration using python standard ‘Logging’ package.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import logging

loglevel = os.environ.get('loglevel','DEBUG').upper()
logging.basicConfig(filename='logfile.log',
format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p',
level=loglevel)
</code></pre></div></div>
<p>Here we are setting some common options like log file name, attributes of log output, datetime format, loglevel. We are getting the loglevel from environment variable instead of providing fixed value.</p>

<p>Python logging package have following loglevel — <code class="language-plaintext highlighter-rouge">DEBUG, INFO, WARNING, ERROR, CRITICAL</code>, to be used accordingly. By setting the loglevel from environment variable, we can use the below workflow -</p>

<ol>
  <li>In a piece of code, we write a debug level log message to track an expected output
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> logging.debug('Running for loop with {} value'.format(value))
</code></pre></div>    </div>
  </li>
  <li>In a exception case, we catch the exception and generate a ERROR level log
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> logging.error('Exception occurred, unable to process for {} value'.format(value))
</code></pre></div>    </div>
  </li>
  <li>Now, in development stage we would want to view both the logs. However in production, we will only be interested in the <code class="language-plaintext highlighter-rouge">ERROR</code> log. So, after deployment, we simply change the loglevel by running <code class="language-plaintext highlighter-rouge">export loglevel=ERROR</code> which will limit the log messages to <code class="language-plaintext highlighter-rouge">ERROR</code> type only. Again, if we want to debug the production application and want to view the <code class="language-plaintext highlighter-rouge">DEBUG</code> level as well, we can simple change the loglevel, without making any code or application state updates.</li>
</ol>

<h2 id="references">References</h2>

<ol>
  <li><a href="https://docs.python.org/3/howto/logging.html">Python Logging documentation</a></li>
  <li><a href="https://www.loggly.com/ultimate-guide/python-logging-basics/">Loggy — python logging</a></li>
</ol>]]></content><author><name>Rajarshi Ghosh</name></author><category term="python" /><summary type="html"><![CDATA[Introduction]]></summary></entry><entry><title type="html">How to create custom Nginx log file</title><link href="https://rajarshig.github.io/posts/how-to-create-custom-nginx-log-file/" rel="alternate" type="text/html" title="How to create custom Nginx log file" /><published>2019-10-12T00:00:00+00:00</published><updated>2019-10-12T00:00:00+00:00</updated><id>https://rajarshig.github.io/posts/how-to-create-custom-nginx-log-file</id><content type="html" xml:base="https://rajarshig.github.io/posts/how-to-create-custom-nginx-log-file/"><![CDATA[<p>Nginx is one of the most widely used web server, regarded highly for its <u>performance &amp; simplicity</u>. Log files are a common requirement for web server configurations. Let’s see how can we create nginx log files with customised values.</p>

<p>For example. let’s say we have setup a web API with Nginx. Now we need to monitor various metrics like number of API access, user-agent, response status etc. Below are the steps -</p>

<ol>
  <li>Define access &amp; error log file: As per default nginx configuration at /etc/nginx/nginx.conf, below log files are defined
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
</code></pre></div>    </div>
    <p>We can define different log files as well, in virtual blocks configuration, at /etc/nginx/sites-available/[virtual_block_file]</p>
  </li>
  <li>Create one or more custom log format: We can create log format specifications with a name
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>log_format myapilogformat '$remote_addr - $remote_user xxx[$time_local]xxx '
 '"$request" $status $body_bytes_sent '
 '"$http_referer" "$http_user_agent" $response_time ';
</code></pre></div>    </div>
  </li>
  <li>
    <p>Update log file with log format: Now we have to update the access_log / error_log to work as per provided log format as below</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>access_log /var/log/nginx/access.log myapilogformat;
</code></pre></div>    </div>
  </li>
  <li>Save &amp; test if no error present
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nginx -t   #tests all nginx configurations
</code></pre></div>    </div>
    <p>If error shown, check for syntax/ spelling errors etc. If no error found, restart nginx</p>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo service nginx restart
</code></pre></div>    </div>
  </li>
</ol>

<p>Reference:</p>
<ul>
  <li>Nginx format options <a href="http://nginx.org/en/docs/http/ngx_http_log_module.html">here</a></li>
</ul>]]></content><author><name>Rajarshi Ghosh</name></author><category term="devops" /><summary type="html"><![CDATA[Nginx is one of the most widely used web server, regarded highly for its performance &amp; simplicity. Log files are a common requirement for web server configurations. Let’s see how can we create nginx log files with customised values.]]></summary></entry></feed>