How can I add a new value for a multi-value field programmatically?
Architectually speaking, it would be much better if you use custom table for this functionality.You can take a look for inspiration (or even use) the following module:

https://www.drupal.org/project/uiplog

From the description of the project: 
User IP Log is a simple module that logs the IP address of users on login event to table {uiplog}.

Updated answer:
Since you want to do it yourself. You can implement a hook_user_login in your custom module.
https://api.drupal.org/api/drupal/core%21modules%21user%21user.api.php/function/hook_user_login/8.2.x

Inside you can just paste the following code.

Assumptions/ notes :


This is simple text field is from the type: "Text (plain)". If
you choose any other option I am not sure if this snippet would work
for you.
The machine name of the field is field_field_1. Not the best name but
you could quite easily change that on line 5.


I have added quite a few sanity checks that I think would be helpful on the long run.

// Load the current user.
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()-&gt;id());

// The machine name of the field.
$field_name = 'field_field_1';
// Sanity check against the machine name of the field.
if ($user-&gt;hasField($field_name)) {
  $field_config = \Drupal\field\Entity\FieldStorageConfig::loadByName('user', $field_name);
  // Checks if has unlimited cardinality, otherwise the appendItem will throw
  // weird error.
  if ($field_config-&gt;getCardinality() == '-1') {
    // This is a fancy way to return $_SERVER['REMOTE_ADDR'].
    // Keep in mind that on localhost, this will return ::1.
    $a = \Drupal::request()-&gt;getClientIp();
    $user-&gt;$field_name-&gt;appendItem(\Drupal::request()-&gt;getClientIp());
  }
  $user-&gt;save();
}


Regards,

Oleg