diff --git a/smartmontools/ChangeLog b/smartmontools/ChangeLog
index e8543ec5a0d462f4304818b670d1ee6021f018a9..08893ef75132f0a993774054b9c24907aa35ef72 100644
--- a/smartmontools/ChangeLog
+++ b/smartmontools/ChangeLog
@@ -1,5 +1,12 @@
 $Id$
 
+2022-02-20  Douglas Gilbert  <dgilbert@interlog.com>
+
+	smartctl.cpp, scsiprint.cpp: implement the change to
+	TapeAlert handling documented in the previous commit.
+	Add --log=tapealert option to explicitly fetch the
+	Tape Alert log page. Tweak some tape-specific formatting.
+
 2022-02-19  Douglas Gilbert  <dgilbert@interlog.com>
 
 	smartctl.8.in: proposed change to TapeAlert handling. No code
diff --git a/smartmontools/scsiprint.cpp b/smartmontools/scsiprint.cpp
index 6a2a1daceacfccb0eb4384e3de1b615fc4384c8b..6b716ef99a8b2a38f2aeec715a08c556937b7a08 100644
--- a/smartmontools/scsiprint.cpp
+++ b/smartmontools/scsiprint.cpp
@@ -391,7 +391,8 @@ scsiGetSmartData(scsi_device * device, bool attribs)
 static const char * const severities = "CWI";
 
 static int
-scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
+scsiPrintActiveTapeAlerts(scsi_device * device, int peripheral_type,
+                          bool from_health)
 {
     unsigned short pagelength;
     unsigned short parametercode;
@@ -399,6 +400,8 @@ scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
     const char *s;
     const char *ts;
     int failures = 0;
+    const char * pad = from_health ? "" : "  ";
+    static const char * const tapealert_s = "scsi_tapealert";
 
     print_on();
     if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, 0, gBuf,
@@ -408,13 +411,13 @@ scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
         return -1;
     }
     if (gBuf[0] != 0x2e) {
-        pout("TapeAlerts %s Failed\n", logSenStr);
+        pout("%sTapeAlerts %s Failed\n", pad, logSenStr);
         print_off();
         return -1;
     }
     pagelength = sg_get_unaligned_be16(gBuf + 2);
 
-    json::ref jref = jglb["scsi_tapealert"]["status"];
+    json::ref jref = jglb[tapealert_s]["status"];
     for (s=severities, k = 0, j = 0; *s; s++, ++k) {
         for (i = 4, m = 0; i < pagelength; i += 5, ++k, ++m) {
             parametercode = sg_get_unaligned_be16(gBuf + i);
@@ -425,9 +428,9 @@ scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
                     scsiTapeAlertsTapeDevice(parametercode);
                 if (*ts == *s) {
                     if (!failures)
-                        pout("TapeAlert Errors (C=Critical, W=Warning, "
-                             "I=Informational):\n");
-                    jout("[0x%02x] %s\n", parametercode, ts);
+                        jout("%sTapeAlert Errors (C=Critical, W=Warning, "
+                             "I=Informational):\n", pad);
+                    jout("%s[0x%02x] %s\n", pad, parametercode, ts);
                     jref[j]["descriptor_idx"] = m + 1;
                     jref[j]["parameter_code"] = parametercode;
                     jref[j]["string"] = ts;
@@ -440,8 +443,8 @@ scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
     print_off();
 
     if (! failures) {
-        jout("TapeAlert: OK\n");
-        jglb["scsi_tapealert"]["status"] = "Good";
+        jout("%sTapeAlert: OK\n", pad);
+        jglb[tapealert_s]["status"] = "Good";
     }
 
     return failures;
@@ -2353,7 +2356,7 @@ show_protocol_specific_port_page(unsigned char * resp, int len)
         if (SCSI_TPROTO_SAS != (0xf & ucp[4]))
             return 0;   /* only decode SAS log page */
         if (0 == k)
-            jout("Protocol Specific port log page for SAS SSP\n");
+            jout("\nProtocol Specific port log page for SAS SSP\n");
         show_sas_port_param(j, ucp, param_len);
         k += param_len;
         ucp += param_len;
@@ -3122,7 +3125,7 @@ scsiPrintEnviroReporting(scsi_device * device)
 int
 scsiPrintMain(scsi_device * device, const scsi_print_options & options)
 {
-    int checkedSupportedLogPages = 0;
+    bool checkedSupportedLogPages = false;
     uint8_t peripheral_type = 0;
     int returnval = 0;
     int res, durationSec;
@@ -3322,15 +3325,17 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
 
     if (options.smart_check_status) {
         scsiGetSupportedLogPages(device);
-        checkedSupportedLogPages = 1;
+        checkedSupportedLogPages = true;
         if (is_tape) {
             if (gTapeAlertsLPage) {
                 if (options.drive_info) {
                     jout("TapeAlert Supported\n");
                     jglb["tapealert"]["supported"] = true;
                 }
-                if (-1 == scsiGetTapeAlertsData(device, peripheral_type))
-                    failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
+                if (options.health_opt_count > 1) {
+                    if (-1 == scsiPrintActiveTapeAlerts(device, peripheral_type, true))
+                        failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
+                }
             } else {
                 jout("TapeAlert Not Supported\n");
                 jglb["tapealert"]["supported"] = false;
@@ -3348,8 +3353,10 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
     }
 
     if (is_disk && options.smart_ss_media_log) {
-        if (! checkedSupportedLogPages)
+        if (! checkedSupportedLogPages) {
             scsiGetSupportedLogPages(device);
+            checkedSupportedLogPages = true;
+        }
         res = 0;
         if (gSSMediaLPage)
             res = scsiPrintSSMedia(device);
@@ -3362,8 +3369,10 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         any_output = true;
     }
     if (options.smart_vendor_attrib) {
-        if (! checkedSupportedLogPages)
+        if (! checkedSupportedLogPages) {
             scsiGetSupportedLogPages(device);
+            checkedSupportedLogPages = true;
+        }
         if (gEnviroReportingLPage && options.smart_env_rep)
             scsiPrintEnviroReporting(device);
         else if (gTempLPage)
@@ -3387,8 +3396,10 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         any_output = true;
     }
     if (options.smart_error_log) {
-        if (! checkedSupportedLogPages)
+        if (! checkedSupportedLogPages) {
             scsiGetSupportedLogPages(device);
+            checkedSupportedLogPages = true;
+        }
         scsiPrintErrorCounterLog(device);
         if (gPendDefectsLPage)
             scsiPrintPendingDefectsLPage(device);
@@ -3398,8 +3409,10 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         any_output = true;
     }
     if (options.smart_selftest_log) {
-        if (! checkedSupportedLogPages)
+        if (! checkedSupportedLogPages) {
             scsiGetSupportedLogPages(device);
+            checkedSupportedLogPages = true;
+        }
         res = 0;
         if (gSelfTestLPage)
             res = scsiPrintSelfTest(device);
@@ -3412,8 +3425,10 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         any_output = true;
     }
     if (options.smart_background_log && is_disk) {
-        if (! checkedSupportedLogPages)
+        if (! checkedSupportedLogPages) {
             scsiGetSupportedLogPages(device);
+            checkedSupportedLogPages = true;
+        }
         res = 0;
         if (gBackgroundResultsLPage)
             res = scsiPrintBackgroundResults(device, false);
@@ -3426,8 +3441,10 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         any_output = true;
     }
     if (options.smart_background_log && is_zbc) {
-        if (! checkedSupportedLogPages)
+        if (! checkedSupportedLogPages) {
             scsiGetSupportedLogPages(device);
+            checkedSupportedLogPages = true;
+        }
         res = 0;
         if (gZBDeviceStatsLPage)
             res = scsiPrintZBDeviceStats(device);
@@ -3441,21 +3458,44 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         any_output = true;
 
     }
-    if (options.tape_device_stats && is_tape) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(device);
-        res = 0;
-        if (gTapeDeviceStatsLPage)
-            res = scsiPrintTapeDeviceStats(device);
-        else {
-            pout("Device does not support (tape) device characteristics "
-                 "(SSC) logging\n");
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+    if (is_tape) {
+        if (options.tape_device_stats) {
+            if (! checkedSupportedLogPages) {
+                scsiGetSupportedLogPages(device);
+                checkedSupportedLogPages = true;
+            }
+            res = 0;
+            if (gTapeDeviceStatsLPage) {
+                jout("\nDevice Statistics (SSC, tape) log page:\n");
+                res = scsiPrintTapeDeviceStats(device);
+            } else {
+                pout("Device does not support (tape) device characteristics "
+                     "(SSC) logging\n");
+                failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+            }
+            if (0 != res)
+                failuretest(OPTIONAL_CMD, returnval|=res);
+            any_output = true;
+        }
+        if (options.tape_alert) {
+            if (! checkedSupportedLogPages) {
+                scsiGetSupportedLogPages(device);
+                // checkedSupportedLogPages = true;     // not needed when last
+            }
+            res = 0;
+            if (gTapeAlertsLPage) {
+                jout("\nTape Alert log page:\n");
+                res = scsiPrintActiveTapeAlerts(device, peripheral_type, false);
+            } else {
+                pout("Device does not support TapeAlert logging\n");
+                failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+            }
+            if (res < 0)
+                failuretest(OPTIONAL_CMD, returnval|=res);
+            if ((scsi_debugmode > 0) && (res == 0))
+                pout("TapeAlerts only printed if active, so none printed is good\n");
+            any_output = true;
         }
-        if (0 != res)
-            failuretest(OPTIONAL_CMD, returnval|=res);
-        any_output = true;
-
     }
     if (options.smart_default_selftest) {
         if (scsiSmartDefaultSelfTest(device))
diff --git a/smartmontools/scsiprint.h b/smartmontools/scsiprint.h
index 5449257dc4221c85b2002b3a9891bd2ce1db970f..3a06c836b4ffaa24e6ee64e8a8d275dec54e3fb1 100644
--- a/smartmontools/scsiprint.h
+++ b/smartmontools/scsiprint.h
@@ -43,6 +43,7 @@ struct scsi_print_options
   bool sasphy = false, sasphy_reset = false;
 
   bool tape_device_stats = false;
+  bool tape_alert = false;
   
   bool get_wce = false, get_rcd = false;
   short int set_wce = 0, set_rcd = 0;  // disable(-1), enable(1) cache
@@ -53,6 +54,8 @@ struct scsi_print_options
   int set_standby = 0;          // set(1..255->0..254) standby timer
   bool set_standby_now = false; // set drive to standby
   bool set_active = false;      // set drive to active
+
+  int health_opt_count = 0;	// TapeAlert log page only read if this value > 1
 };
 
 int scsiPrintMain(scsi_device * device, const scsi_print_options & options);
diff --git a/smartmontools/smartctl.8.in b/smartmontools/smartctl.8.in
index 1de878877148c86f2a5d12051a1e4d561a0939bd..741d1986a1db6024f3dc68d58741f0f60a784833 100644
--- a/smartmontools/smartctl.8.in
+++ b/smartmontools/smartctl.8.in
@@ -1567,6 +1567,11 @@ drives.
 Protocol Specific log page (log page 0x18).  If \*(Aq\-l sasphy,reset\*(Aq
 is specified, all counters are reset after reading the values.
 .Sp
+.I tapealert
+\- [SCSI tape drives and changers] prints values and descriptions of
+the (SSC) Tape Alert log page. See \fBTAPE DRIVES\fP below for issue
+associated with printing this log page.
+.Sp
 .I tapedevstat
 \- [SCSI tape drives and changers] prints values and descriptions of
 the (SSC) Device Statistics log page.
@@ -2291,7 +2296,9 @@ standards can be found at <\fBhttps://www.t10.org/\fP> .
 Many SMART related features of SCSI disks are shared by SCSI tape drives.
 One important tape\-specific log page is called "TapeAlert" which is used
 to report abnormal conditions. Unlike most other log pages the TapeAlert
-log page clears pending alerts after that page is fetched (i.e. read from
+log page
+.B clears
+pending alerts after that page is fetched (i.e. read from
 the tape drive). To be more precise, the TapeAlert log page is cleared
 for the I_T nexus (initiator-target pair) that sent the (SCSI LOG SENSE)
 command; so another initiator (e.g.  a HBA on another machine) will still
diff --git a/smartmontools/smartctl.cpp b/smartmontools/smartctl.cpp
index 2f7cbe5ccc2508549dcc1804df328b76feb2d4d0..1021e7a109bad2e40b9c95b76f382392ee8a37ba 100644
--- a/smartmontools/smartctl.cpp
+++ b/smartmontools/smartctl.cpp
@@ -493,6 +493,7 @@ static int parse_options(int argc, char** argv, const char * & type,
     case 'H':
       ataopts.smart_check_status = scsiopts.smart_check_status = nvmeopts.smart_check_status = true;
       scsiopts.smart_ss_media_log = true;
+      ++scsiopts.health_opt_count;
       break;
     case 'F':
       if (!strcmp(optarg, "swapid"))
@@ -550,6 +551,8 @@ static int parse_options(int argc, char** argv, const char * & type,
         ataopts.sct_temp_sts = true;
       } else if (!strcmp(optarg,"scttemphist")) {
         ataopts.sct_temp_hist = true;
+      } else if (!strcmp(optarg,"tapealert")) {
+        scsiopts.tape_alert = true;
       } else if (!strcmp(optarg,"tapedevstat")) {
         scsiopts.tape_device_stats = true;