Repository: apache/airflow

Issue:
Unable to fetch CloudWatch Logs of previous run attempts
### Apache Airflow version

2.7.0

### What happened

After upgrading to `apache-airflow-providers-amazon==8.5.1`, I am no longer able to view logs from previous run attempts. 

Airflow is able to find the log stream successfully, but there's no content viewable (even though there are logs in the actual streams):
```
REDACTED.us-west-2.compute.internal
*** Reading remote log from Cloudwatch log_group: REDACTED log_stream: dag_id=REDACTED/run_id=REDACTED/task_id=REDACTED/attempt=1.log.
```

I believe this issue occurred from #33231 -  Looking at the [CloudWatch Logs code](https://github.com/apache/airflow/blob/providers-amazon/8.5.1/airflow/providers/amazon/aws/log/cloudwatch_task_handler.py#L109-L133), I think `task_instance.start_date` and `task_instance.end_date` somehow refer to its __latest__ run, and so the log contents are getting filtered out on previous attempts.


### What you think should happen instead

_No response_

### How to reproduce

1. Configure environment with remote CloudWatch logging
2. Run task
3. Clear task and re-run
4. The logs for the first attempt now no longer show

### Operating System

Debian 11

### Versions of Apache Airflow Providers

apache-airflow-providers-amazon==8.5.1

### Deployment

Other

### Deployment details

_No response_

### Anything else

_No response_

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)



Discussion:
Yep, seem like. Just because `task_instance.start_date` and `task_instance.end_date` only stored for latest TaskInstance run and after restart it refers to new one

cc: @vincbeck  
Arg ... And If I dont set any boundary, then logs are not working either ... I need to think about it and see if there is any solution
Any idea which date and time I should take then? Do we have this information somewhere actually?
Unfortunetly, I don't have a right answer, because there some kind different side effects might exists. For example even for last task run it might return incomplete or empty data, for example user do not sync time as result wrong data stored into the Airflow Database.

I'm also not familiar with performance of Cloudwatch, only familiar with huge bills in case when I was ignored what I send to Cloudwatch 😄 

IMHO, I though there is some fundamental issue with remote logging - result not cached, so each time it retrieved from remote storage again. 😢 

Resolving patch:
diff --git a/airflow/providers/amazon/aws/log/cloudwatch_task_handler.py b/airflow/providers/amazon/aws/log/cloudwatch_task_handler.py
--- a/airflow/providers/amazon/aws/log/cloudwatch_task_handler.py
+++ b/airflow/providers/amazon/aws/log/cloudwatch_task_handler.py
@@ -114,9 +114,6 @@ def get_cloudwatch_logs(self, stream_name: str, task_instance: TaskInstance) ->
         :param task_instance: the task instance to get logs about
         :return: string of all logs from the given log stream
         """
-        start_time = (
-            0 if task_instance.start_date is None else datetime_to_epoch_utc_ms(task_instance.start_date)
-        )
         # If there is an end_date to the task instance, fetch logs until that date + 30 seconds
         # 30 seconds is an arbitrary buffer so that we don't miss any logs that were emitted
         end_time = (
@@ -127,7 +124,6 @@ def get_cloudwatch_logs(self, stream_name: str, task_instance: TaskInstance) ->
         events = self.hook.get_log_events(
             log_group=self.log_group,
             log_stream_name=stream_name,
-            start_time=start_time,
             end_time=end_time,
         )
         return "\n".join(self._event_to_str(event) for event in events)


Test patch:
diff --git a/tests/providers/amazon/aws/log/test_cloudwatch_task_handler.py b/tests/providers/amazon/aws/log/test_cloudwatch_task_handler.py
--- a/tests/providers/amazon/aws/log/test_cloudwatch_task_handler.py
+++ b/tests/providers/amazon/aws/log/test_cloudwatch_task_handler.py
@@ -155,35 +155,19 @@ def test_read(self):
         )
 
     @pytest.mark.parametrize(
-        "start_date, end_date, expected_start_time, expected_end_time",
+        "end_date, expected_end_time",
         [
-            (None, None, 0, None),
-            (datetime(2020, 1, 1), None, datetime_to_epoch_utc_ms(datetime(2020, 1, 1)), None),
-            (
-                None,
-                datetime(2020, 1, 2),
-                0,
-                datetime_to_epoch_utc_ms(datetime(2020, 1, 2) + timedelta(seconds=30)),
-            ),
-            (
-                datetime(2020, 1, 1),
-                datetime(2020, 1, 2),
-                datetime_to_epoch_utc_ms(datetime(2020, 1, 1)),
-                datetime_to_epoch_utc_ms(datetime(2020, 1, 2) + timedelta(seconds=30)),
-            ),
+            (None, None),
+            (datetime(2020, 1, 2), datetime_to_epoch_utc_ms(datetime(2020, 1, 2) + timedelta(seconds=30))),
         ],
     )
     @mock.patch.object(AwsLogsHook, "get_log_events")
-    def test_get_cloudwatch_logs(
-        self, mock_get_log_events, start_date, end_date, expected_start_time, expected_end_time
-    ):
-        self.ti.start_date = start_date
+    def test_get_cloudwatch_logs(self, mock_get_log_events, end_date, expected_end_time):
         self.ti.end_date = end_date
         self.cloudwatch_task_handler.get_cloudwatch_logs(self.remote_log_stream, self.ti)
         mock_get_log_events.assert_called_once_with(
             log_group=self.remote_log_group,
             log_stream_name=self.remote_log_stream,
-            start_time=expected_start_time,
             end_time=expected_end_time,
         )